在PreAccess这个阶段主要有2个模块。
一、limit_conn:限制并发连接数。这个模块默认是编译进Nginx中的,可以通过--without-http_limit_conn_limit_module来禁用。
生效阶段:是在NGX_HTTP_PREACCESS_PHASE阶段。
生效范围:全部的worker进程,因为它使用了共享内存。所有zone指令都是在分配共享内存。
进入preaccess阶段前是不生效的,也就是说之前说的rewrite,find_config阶段 limit_conn模块是不会生效的。
限制连接的有效性,取决于key的设计。比如我们如果是限制客户端的并发连接数,而我们的Nginx之前如果有slb,这个时候 我们要用postread阶段的realip模块获取到真实ip。根据真实ip再来做并发连接限制。
语法:
// 定义共享内存 limit_conn_zone $key zone=$name:$size; // key:关键字 // name:共享内存的名字 // size:共享内存的大小 limit_conn $zone $number; // zone:上面定义的name // number:并发连接数
二、limit_req:限制并发请求数,默认也是编译进nginx的。
生效阶段:是在NGX_HTTP_PREACCESS_PHASE阶段。
生效算法:leaky bucket算法。
生效范围:全部的worker进程,也是基于共享内存设计的。
语法
limit_req_zone $key zone=$name rate=$rate // key:关键字 // name:共享内存的名字 // size:共享内存的大小 // rate:速率 limit_req zone=$name [burst=$number] [nodelay] name:上面共享内存定义的名字 number:就是缓冲区里可容纳的请求数量 nodelay:在缓冲区里的指令也返回错误
leaky bucket算法:主要就是中间有个容器,可以控制一定的请求数量,以3M/s匀速给到Nginx。如果超过则会留在容器中,如果超过容器的容量,则会返回错误。
leaky bucket算法示意图
举个例子:
// 声明 限制连接的 共享内存 addr 大小为10m limit_conn_zone $binary_remote_addr zone=addr:10m; // 声明 限制请求的 共享内存 one 大小为10m limit_req_zone $binary_remote_addr zone=one:10m rate=2r/m; location /{ limit_conn_status 500; limit_conn_log_level warn; limit_rate 50; limit_conn addr 1; limit_req zone=one; }
我们来考虑个问题:
limit_req与limit_conn配置同时生效,哪个有效?
limit_req在limit_conn之前,如果先触发了limit_req那么limit_conn就没有机会执行了。
#Nginx##程序员#