go-kit 微服务 限流 (uber/ratelimit 和

2020-01-10  本文已影响0人  hwholiday

golang/rate 简介(golang.org/x/time/rate)

//第一个参数是 r Limit。代表每秒可以向 Token 桶中产生多少 token
//第二个参数是 b int。b 代表 Token 桶的容量大小
golangLimit := rate.NewLimiter(10, 1)
//golangLimit 其令牌桶大小为 1, 以每秒 10 个 Token 的速率向桶中放置 Token。

uber/ratelimit 简介(go.uber.org/ratelimit)

//一秒请求一次
uberLimit := ratelimit.New(1)         
//使用方法
uberLimit.Take()        

Endpoint层修改

func NewGolangRateAllowMiddleware(limit *rate.Limiter) endpoint.Middleware {
    return func(next endpoint.Endpoint) endpoint.Endpoint {
        return func(ctx context.Context, request interface{}) (response interface{}, err error) {
            if !limit.Allow() {
                return "", errors.New("limit req  Allow")
            }
            return next(ctx, request)
        }
    }
}

func NewUberRateMiddleware(limit ratelimit.Limiter) endpoint.Middleware {
    return func(next endpoint.Endpoint) endpoint.Endpoint {
        return func(ctx context.Context, request interface{}) (response interface{}, err error) {
            limit.Take()
            return next(ctx, request)
        }
    }
}
func NewEndPointServer(svc v4_service.Service, log *zap.Logger, limit *rate.Limiter, limiter ratelimit.Limiter) EndPointServer {
    var addEndPoint endpoint.Endpoint
    {
        addEndPoint = MakeAddEndPoint(svc)
        addEndPoint = LoggingMiddleware(log)(addEndPoint)
        addEndPoint = AuthMiddleware(log)(addEndPoint)
        addEndPoint = NewUberRateMiddleware(limiter)(addEndPoint)
    }
    var loginEndPoint endpoint.Endpoint
    {
        loginEndPoint = MakeLoginEndPoint(svc)
        loginEndPoint = LoggingMiddleware(log)(loginEndPoint)
        loginEndPoint = NewGolangRateAllowMiddleware(limit)(loginEndPoint)
    }
    return EndPointServer{AddEndPoint: addEndPoint, LoginEndPoint: loginEndPoint}
}

激动人心的时刻来了,修改main方法

utils.NewLoggerServer()
golangLimit := rate.NewLimiter(10, 1) //每秒产生10个令牌,令牌桶的可以装1个令牌
uberLimit := ratelimit.New(1)         //一秒请求一次
server := v4_service.NewService(utils.GetLogger())
endpoints := v4_endpoint.NewEndPointServer(server, utils.GetLogger(), golangLimit, uberLimit)
httpHandler := v4_transport.NewHttpHandler(endpoints, utils.GetLogger())
utils.GetLogger().Info("server run 0.0.0.0:8888")
_ = http.ListenAndServe("0.0.0.0:8888", httpHandler))

日志(一秒请求100次接口)

2020-01-03 09:46:30     DEBUG   v4_transport/transport.go:70    5fd6eae3-32ea-5a24-9507-ed3c865f2e50    {" 开始解析请求数据": {"a":1,"b":1}}
2020-01-03 09:46:31     DEBUG   v4_transport/transport.go:70    ca39186b-c4e1-5976-bb02-f5e484aeca48    {" 开始解析请求数据": {"a":1,"b":1}}
2020-01-03 09:46:32     DEBUG   v4_transport/transport.go:70    691bfdf1-6701-553f-ae78-d443eff6fb6b    {" 开始解析请求数据": {"a":1,"b":1}}
......
可以看到请求是按照我们控制的一秒一秒请求的
2020-01-03 09:42:17     DEBUG   v4_transport/transport.go:75    cc74b82d-4fa9-558c-acd3-ad2ea292dfdd    {"请求结束封装返回值":"token"}}
2020-01-03 09:42:17     WARN    v4_transport/transport.go:20    c1a00c56-edad-55b0-b546-076a0d070086    {"error": "limit req  Allow"}
2020-01-03 09:42:17     DEBUG   v4_transport/transport.go:75    2c8ab986-c300-5df1-99fc-0d88c8db8c40    {"请求结束封装返回值":"token"}}
2020-01-03 09:42:17     WARN    v4_transport/transport.go:20    8e5dc5d4-e048-56c7-9a42-33863843cd67    {"error": "limit req  Allow"}
......

结语

完整代码地址

联系 QQ: 3355168235

上一篇下一篇

猜你喜欢

热点阅读