限流部分:
限流方案:
现有限流算法:
滑动窗口限流:
优点:细分时间精度可以避免请求超过阈值,可以应对简单的突发流量
缺点:使用内存或者redis来维护窗口,如果时间颗粒度太细,会造空间容量过大。
漏桶限流:
- 优点:基本实现了平滑处理,在单位时间内,可以控制请求数量。
- 缺点:不考虑服务器负载,如果有大量请求会对请求进行缓存,按照漏桶流量进行处理。
令牌桶限流:
- 优点: 限制平均流入速率,允许一定程度的突发请求(支持一次拿多个令牌)
- 缺点: 不好估算流入速度, 需要根据不同机器或环境进行配置。
自适应限流:
优点:可以根据硬件配置,设置load 或者 cpu 占用率,根据设置的cpu占用率和load 阈值, 获取过去一段时间内的请求数量。将这个数量作为限流,如果系统负载达到这个显示,将这个请求数量作为请求阈值。
缺点:根据系统资源利用率进行限流,会因为其它程序或进程的高cpu占用率触发限流。这部分可以采用docker 封装,获取docker 的相关占用率进行避免。
参考:
kratos/ratelimit.md at v1.0.x · go-kratos/kratos (github.com)
代码设计方式:
抽象接口:
type GFLimiter interface { ShouldAllow() bool //是否允许 accept() error //通过函数 reject() error //拒绝函数 }
完成两种限流方式(令牌桶限流和自适应限流),原因如下:
- 在非容器化的环境中,cpu和load一般都会收其他进程影响,所以,使用令牌桶比自适应更合适。
- 在容器化环境中,使用cpu来做为指标,可以更好的控制流量,不需要手动设置。
- 除此之外,用户可以通过interface 实现自己的限流定义。
熔断部分:
算法部分
- Hystrix 算法,类似于固定窗口, 到达出错阈值之后,冷却一段时间,在继续执行。
- google_sre 算法: 自适应保护,根据请求成功概率,来控制熔断概率,相较于Hystrix算法,恢复更快,可以在下游服务压力大的时候进行保护,向下游服务发送瞬时大量请求的情况较少。
代码实现计划:
- 计划采用google_sre 算法, 参考go-kratos/aegis 的实现。
- 代码实现部分: 计划在 gogf/katyusha 的krpc 中实现熔断器,用户可以在使用krpc的时候选择是否开启。
- 在熔断器中,用户可以设置降级函数,如果熔断器返回错误,用户可以自定义逻辑,这部分参考go-mirco 中的 Hystrix Client Wrapper 的实现方式。
2 Comments
郭强
ZhangDafang 限流的方案在业内都比较成熟了,我看你这已经参考了成熟的方案,挺好的。对于
GoFrame
框架来讲,对于限流组件的设计和引入依旧采用模块化和接口化的形式。在你的设计中,我看到有默认的限流实现,这个实现看起来会引入一些比较重的第三方依赖。我有以下建议:gcache/gcfg/gsession
等接口化设计组件的实现,开发者可以通过Adapter
的方式注入自定义的算法实现或者第三方实现。我觉得你可以把具体的接口定义和对象管理设计好,现在文档中的
GFLimiter
那个interface
比较简单。你可以稍微准备点PPT,定一个时间给大伙分享一下。ZhangDafang
好的,这两天仔细看一下这部session那部分代码。 整理下思路。准备个ppt