在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
一、项目架构图
二、现有问题
三、解决方案
四、具体实现 新请求限流:使用 time/rate 实现令牌桶逻辑,控制每秒内所接收的新请求数量 在途请求限流:记录当前正在处理的请求数量,当接收到SDK请求时,将 curConcurrency 加1,代表这个请求正在被处理(在途请求);在响应前将 curConcurrency 加1,代表这个请求已经完成。需配置在途请求的最大并发数,只有在当前的 curConcurrency < maxConcurrency 时,才对请求进行处理,否则将请求直接丢弃。
// 构造一个限流器对象 NewLimiter(r, b): r 每秒可向Token桶中产生多少 token,b Token桶的容量大小 limiter := NewLimiter(10, 1); // 令牌桶大小为 1, 以每秒 10 个 token 的速率向桶中放置 Token // Every 方法用来指定向 Token 桶中放置 token 的时间间隔 limit := Every(100 * time.Millisecond); // 每 100ms 往桶中放一个 Token; 一秒钟产生 10 个token limiter := NewLimiter(limit, 1); // 消费方式: // Wait/WaitN: 阻塞消费 // 调用 Wait 方法消费时, 若桶内的token数组长度 不足n(小于n), Wait方法将会阻塞, 直到token数量满足条件位置; 如果桶内token数组满足条件则直接返回 func (lim *Limiter) Wait(ctx context.Context) (err error) func (lim *Limiter) WaitN(ctx context.Context, n int) (err error) // 可设置 ctx(context) 参数的 Deadline、Timeout 来决定此次 Wait 的最长时间 // Allow/AllowN: 桶内token满足条件消费 // AllowN: 截止到某一时刻, 当前桶内token数量是否至少为n个, 满足返回true, 同时从桶内消费n个token; 反之返回false不消费token func (lim *Limiter) Allow() bool func (lim *Limiter) AllowN(now time.Time, n int) bool // Reserve/ReserveN: 对象等待消费 // 调用 ReserveN 方法后, 无论 token 是否充足都会返回一个 Reservation* 对象, 再调用该对象的 Delay 方法, 可返回需要等待的时间, 若等待时间为0, 则无需等待; // 否则必须等待到之后时间后, 才能继续工作; 若期间不想再等待可调用 Cancel方法取消, 它将会把 token 归还 r := lim.Reserve() f !r.OK() { // Not allowed to act! Did you remember to set lim.burst to be > 0 ? return } time.Sleep(r.Delay()) Act() // 执行相关逻辑 // 动态调整速率 //Limiter 支持可以调整速率和桶大小: SetLimit(Limit) // 改变放入 Token 的速率, 接收的参数: 如果为 1、2、3...等数字可直接传递, 如果是将数字保存在变量中时(基本类型 int64、float64...) 必须使用 rate.Limit(variable) 进行转换为 Limit 类型, 即使底层的数据类型是一致 SetBurst(int) // 改变 Token 桶大小
为什么要实现在途请求的限流? 服务当中是以上一秒的总请求数、正常处理请求数、超时请求数作为,下一秒设置令牌桶大小的参考, 控制着当前这1秒应该产生多少token,令牌桶的大小决定了 当前这一秒允许多少个的新请求进入屋子等待服务的响应。将令牌桶想象成大队长,它专用来清点请求数量,放指定数量的请求进屋;虽然大队长能够控制这一秒应该进去多少请求,但它无法控制这群请求什么时候出来,会在屋子里面呆多久的时间。假设每个请求需要5s才能返回响应,每秒假设会由令牌桶大队长放进来100个请求,那么到了第5秒的时候,屋子里面总共会有500个请求,既包括最后1秒的新请求,又包括了前4秒的在途请求。这些请求越积越多,但是屋子只有那么小,最后装不下了,内存也就爆了(总请求数=新请求+在途请求)。而并发控制就是为了解决 令牌桶 无法控制屋子里的总请求数的缺陷。
令牌桶 博客参考链接:
consul 参考链接:
|
请发表评论