一、超压可靠性(过载保护) #
某些情况可能导致系统面临数倍于正常容量的压力
- 集群中某些节点故障
- 客户突发高峰期,节假日前后
1. 量化指标 #
设备正常上线为QPS,当承受N倍压力下,保证QPS*95%的上线成功速率。上线成功速率不代表可以让95%用户都成功上线,只是保证QPS的速率
2. 业界实践 #
2.1. 微信过载控制机制 DAGOR #
https://www.cs.columbia.edu/~ruigu/papers/socc18-final100.pdf
1) 过载判断 #
- 在一个时间窗口中,等待队列所有请求的平均等待时间超过20ms,认为服务发生了过载
2) 请求优先级 #
- 在请求入口处赋予每个请求两个优先级,业务优先级和用户优先级
- 优先级会携带到子调用中
3) 过载处理 #
- 检测到发生过载后,统计上一个时间窗口的请求数量根据优先级画出直方图,计算下一个窗口的预期请求数量(降低5%),使用这个数量在直方图上找到最接近的优先级,调整准入优先级
- 检测到过载恢复,计算下一个窗口的预期请求数(增加1%),继续调整准入优先级
3. 第三方组件限流机制 #
3.1. nginx限流机制 #
1) 基本配置 #
在 nginx 中,主要通过下面的两个配置实现限流限速:
limit_req_zone key zone=name:size rate=rate [sync];
limit_req zone=name [burst=number] [nodelay | delay=number];
例如:
http {
limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;
...
server {
...
location /search/ {
limit_req zone=one burst=5;
}
一个限流配置中有几个要素:
- key 表示计算流速时根据什么来累加计数,比如 limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s; 中把 key 设置为 $binary_remote_addr 意味着根据客户端 IP 进行累加计数,如果同一个 IP 在 1 秒内发起了 10 个任意请求则速率为 10r/s. 可以把 key 理解为队列编号。
- rate 表示要限速值。
- burst 是用于削峰填谷的,下面会详细介绍。
- nodelay 和 delay 是和 burst 配合使用的,下面介绍我们的限流机制时会详细解释。
2) 工作原理 #
- 基于漏桶算法
- rate 是这个桶的开口大小,控制出水的速度
- burst 是这个桶的容量,如果进水的速度太快,就会存在桶里,如果桶里的水满了就溢出,即拒绝请求。
当一个请求进来时,nginx 拿当前时间减去上一个请求进来的时间,然后计算当前速率,看看当前这个请求超速多少了,然后得出这个请求应该延迟多久才能放行,接着设置定时器,定时器到了再继续处理这个请求。
3) 遇到的问题 #
(1) 计算得到的超时时间很长导致无效请求占坑不释放,引发恶性循环 #
- 解决为添加超时机制,超过timeout值直接拒绝,不再等待
(2) burst参数导致所有请求变慢 #
- 当用户请求速率一直超过rate,所有请求等待时间就会越来越长,需要等之前的请求处理完才能处理新的请求
解决方案
- 调低timeout值,可以缓解
- 使用nodelay,桶满之前正常处理,桶满了就开始拒绝请求,保证进入的请求和处理的请求速率一致
(3) 动态调整rate有滞后性 #
解决方案
- 高速路长度调短,灵敏度会高一些
- 使用nodelay参数