Значение ограничения тока системы и реализации кода Golang

задняя часть Go балансировки нагрузки
Значение ограничения тока системы и реализации кода Golang

Это 25-й день моего участия в августовском испытании обновлений. Узнайте подробности события:Испытание августовского обновления

Если ❤️моя статья оказалась полезной, ставьте лайк и подписывайтесь. Это самый большой стимул для меня продолжать техническое творчество.Больше предыдущих статей в моей личной колонке

Значение ограничения тока системы и реализации кода Golang

Значение ограничения тока

Три мощных инструмента для систем с высокой степенью параллелизма: кэширование, понижение версии и ограничение тока.

  • Кэш: улучшите скорость доступа к системе и увеличьте вычислительную мощность, а также увеличьте кеш для соответствующих служб.
  • Понижение уровня: когда нагрузка на сервер резко возрастает, понизьте его в соответствии с бизнес-стратегией, чтобы высвободить ресурсы службы для обеспечения нормального ведения бизнеса.
  • Текущее ограничение: благодаря одновременному ограничению скорости можно добиться отказа в обслуживании, постановки в очередь, ожидания, перехода на более раннюю версию и другой обработки.

Время/скорость ограничения тока дырявого ведра

  • rate.NewLimiter(limit,burst)
  • limit указывает количество токенов, генерируемых в секунду, и максимальное количество токенов, хранящихся в пакете
  • Разрешить определить, можно ли в данный момент получить токен
  • Wait блокирует и ждет, пока не будет получен токен
  • Резерв возвращает время ожидания, после чего переходит к получению токена

отслеживание исходного кода по времени/скорости

  • Рассчитать разницу во времени между последним запросом и текущим запросом
  • Количество токенов, сгенерированных за разницу во времени расчета + количество старых токенов
  • Если токен отрицательный, рассчитайте время ожидания
  • Если токен положительный, после запроса token-1

Добавьте крылья к прокси-серверу шлюза

package middleware

import (
	"fmt"
	"golang.org/x/time/rate"
)

func RateLimiter() func(c *SliceRouterContext) {
	l := rate.NewLimiter(1, 2)
	return func(c *SliceRouterContext) {
		if !l.Allow() {
			c.Rw.Write([]byte(fmt.Sprintf("rate limit:%v,%v", l.Limit(), l.Burst())))
			c.Abort()
			return
		}
		c.Next()
	}
}

Доступ к промежуточному ПО

package main

import (
	"github.com/e421083458/gateway_demo/proxy/middleware"
	"github.com/e421083458/gateway_demo/proxy/proxy"
	"log"
	"net/http"
	"net/url"
)

var addr = "127.0.0.1:2002"

// 熔断方案
func main() {
	coreFunc := func(c *middleware.SliceRouterContext) http.Handler {
		rs1 := "http://127.0.0.1:2003/base"
		url1, err1 := url.Parse(rs1)
		if err1 != nil {
			log.Println(err1)
		}

		rs2 := "http://127.0.0.1:2004/base"
		url2, err2 := url.Parse(rs2)
		if err2 != nil {
			log.Println(err2)
		}

		urls := []*url.URL{url1, url2}
		return proxy.NewMultipleHostsReverseProxy(c, urls)
	}
	log.Println("Starting httpserver at " + addr)

	sliceRouter := middleware.NewSliceRouter()
	sliceRouter.Group("/").Use(middleware.RateLimiter())
	routerHandler := middleware.NewSliceRouterHandler(coreFunc, sliceRouter)
	log.Fatal(http.ListenAndServe(addr, routerHandler))
}

контрольная работа

$ curl '127.0.0.1:2002/abo'
http://127.0.0.1:2004/base/abo
RemoteAddr=127.0.0.1:62366,X-Forwarded-For=127.0.0.1,X-Real-Ip=
headers =map[Accept:[*/*] Accept-Encoding:[gzip] User-Agent:[curl/7.69.1] X-Forwarded-For:[127.0.0.1]]

Administrator@DESKTOP-U15QB8I MINGW64 /d/Dev/workplace/golang/gateway_v1/pratise/proxy/limiter/rate_limiter (master)

$ curl '127.0.0.1:2002/abo'
rate limit:1,2
Administrator@DESKTOP-U15QB8I MINGW64 /d/Dev/workplace/golang/gateway_v1/pratise/proxy/limiter/rate_limiter (master)

$ curl '127.0.0.1:2002/abo'
http://127.0.0.1:2004/base/abo
RemoteAddr=127.0.0.1:62366,X-Forwarded-For=127.0.0.1,X-Real-Ip=
headers =map[Accept:[*/*] Accept-Encoding:[gzip] User-Agent:[curl/7.69.1] X-Forwarded-For:[127.0.0.1]]

Administrator@DESKTOP-U15QB8I MINGW64 /d/Dev/workplace/golang/gateway_v1/pratise/proxy/limiter/rate_limiter (master)

$ curl '127.0.0.1:2002/abo'
rate limit:1,2