赞
踩
在这个图书馆项目中,我们采用令牌桶限流算法,具体原理请参看《分布式高可用-流量控制-1 流控策略》文章。
完整代码:
https://github.com/Justin02180218/micro-kit
在 pkg 下新建目录 ratelimits,创建 ratelimit.go 文件:
在 go kit 的 endpoint 层进行限流,采用装饰器模式
- var ErrLimitExceed = errors.New(" Rate Limit Exceed ")
-
- func NewTokenBucketLimiter(tb *ratelimit.Bucket) endpoint.Middleware {
- return func(next endpoint.Endpoint) endpoint.Endpoint {
- return func(ctx context.Context, request interface{}) (response interface{}, err error) {
- // 从令牌桶中取令牌,如果没有令牌则返回提示信息。
- if tb.TakeAvailable(1) == 0 {
- return nil, ErrLimitExceed
- }
- return next(ctx, request)
- }
- }
- }
配置文件
- ratelimit:
- fillInterval: 1
- capacity: 3
- type RatelimitConfig struct {
- FillInterval int `json:"fillInterval" yaml:"fillInterval"`
- Capacity int `json:"capacity" yaml:"capacity"`
- }
为了测试方便,配置令牌桶的容量为3个,填充间隔为1秒。当并发请求超过3个,就会触发限流,提示错误信息。
修改 main.go
以 library-user-service 为例,其他微服务也是相同的写法
- // 创建令牌桶
- bucket := ratelimit.NewBucket(time.Second*time.Duration(configs.Conf.RatelimitConfig.FillInterval), int64(configs.Conf.RatelimitConfig.Capacity))
- ratelimit := ratelimits.NewTokenBucketLimiter(bucket)
-
- userEndpoints := &endpoint.UserEndpoints{
- RegisterEndpoint: ratelimit(endpoint.MakeRegisterEndpoint(userService)),
- FindByIDEndpoint: ratelimit(endpoint.MakeFindByIDEndpoint(userService)),
- FindByEmailEndpoint: ratelimit(endpoint.MakeFindByEmailEndpoint(userService)),
- FindBooksByUserIDEndpoint: ratelimit(endpoint.MakeFindBooksByUserIDEndpoint(userService)),
- }
下一篇文章,我们给微服务加入服务注册与发现功能。
完整代码:
https://github.com/Justin02180218/micro-kit
更多【分布式专辑】【架构实战专辑】系列文章,请关注公众号
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。