Nginx有个HttpLimitReqModule,可以限制请求的频率,其中有个参数burst在文档http://wiki.nginx.org/HttpLimitReqModule不甚详尽,故读其代码了解之。
源码在src/http/modules/ngx\_http\_limit\_req\_module.c,关于burst的核心代码在这。
//src/http/modules/ngx_http_limit_req_module.c:396
ms = (ngx_msec_int_t) (now - lr->last);
excess = lr->excess - ctx->rate * ngx_abs(ms) / 1000 + 1000;
if (excess < 0) {
excess = 0;
}
*ep = excess;
if ((ngx_uint_t) excess > limit->burst) {
return NGX_BUSY;
}
if (account) {
lr->excess = excess;
lr->last = now;
return NGX_OK;
}
excess初始值是0,假设现在ctx->rate是2000(即2 request/s),这次请求距离上次请求是400ms。
那么excess = 0 – 2000 * 400 / 1000 + 1000 = 200。如果limit->burst是0,那么200 > 0,会返回NGX_BUSY即是503了。
假如burst是1,limit->burst即是1000,那么如果请求是每隔400ms来一个,共需5个才会填满limit->burst(每个请求将会增加200 excess),到第6个才会返回503。
推导出公式,假设设置频率是r request/s,每次请求距离上次请求t ms,设置burst为b,那么返回503的临界请求个数x是
\begin{equation}
x = floor(b * \frac {( 1000 / r )} {( 1000 / r – t )})
\end{equation}