limit_req 的 burst 和 nodelay 到底改变了什么?持续过载时放行多少?limit_conn 和 limit_req 守的是同一件事吗?这篇用 nginx 1.31.6 逐项量出来。
配置 | 放行 | 拒绝(429) | 放行的请求各自的耗时(ms,从小到大) ---------------------+----+---------+------------------------------------ (a) 无 burst | 1 | 29 | 4 (b) burst=5 | 6 | 24 | 6 107 202 305 405 504 (c) burst=5 nodelay | 6 | 24 | 4 7 8 8 9 10 (d) burst=10 delay=3 | 11 | 19 | 8 8 9 9 104 202 303 403 504 604 703 无 burst 时同一时刻只放行 1 个;burst=5 放行 1 + 5 = 6 个,但后面 5 个被排队、每隔 100 ms 放一个(漏桶的“漏”);nodelay 让这 6 个立刻处理,代价是之后要隔够时间才再有额度;delay=3 是折中:前 1 + 3 个立刻,后面的排队延迟,总共 burst=10 个位置
burst 决定能多放几个,nodelay / delay 决定这些多放的请求排队还是立刻处理。
配置 | 100 个请求里放行 | 按发出时刻,第 0..4 秒各放行 ----------------+------------+--------------------- burst 0 | 40 | [9, 8, 9, 7, 7] burst 5 | 55 | [15, 10, 10, 10, 10] burst 5 nodelay | 55 | [15, 10, 10, 10, 10] 速率上限就是 rate × 时间:5 秒 × 10 个/秒 = 50 个;burst 额外送一次性的额度(burst 5 最多多放 5 个,即 55);burst 0 时放行的比 50 还少一些,我的解释是请求每 50 ms 到一个,而放行要求距离上一个放行的请求至少 100 ms,到达时刻稍有抖动就差一点点被拒绝(这个解释没有单独验证);burst 排队放行的请求要等一会儿才有响应(漏桶每 100 ms 放一个),如果 client 是等响应再发下一个的(闭环),它自己的发送速率会被拖慢到 rate,于是一个都不会被拒绝,这里用开环才看得到拒绝
放行总量是 rate × 时间加 burst;闭环 client 会被排队拖慢到 rate,所以看不到拒绝。
配置 | 放行 | 拒绝(429) --------------------------------------+----+-------- limit_conn c 3 | 3 | 9 limit_req rate=10r/s burst=20 nodelay | 12 | 0
数的是同时在处理的请求,和 limit_req 数到达速率不同。