惊群现象:所有的工作进程都在等待一个socket,当socket客户端连接时,所有工作线程都被唤醒,但最终有且仅有一个工作线程去处理该连接,其他进程又要进入睡眠状态。
Nginx通过控制争抢处理socket的进程数量和抢占ngx_accept_mutex锁解决惊群现象。只有一个ngx_accept_mutex锁,谁拿到锁,谁处理该socket的请求。
如果当前进程的连接数>最大连接数*7/8,则该进程不参与本轮竞争。
//nginx的每个worker进程在函数ngx_process_events_and_timers中处理事件。下面代码是ngx_process_events_and_timers()函数的核心部分。
void ngx_process_events_and_timers(ngx_cycle_t *cycle)
{
//ngx_use_accept_mutex表示是否需要通过对accept加锁来解决惊群问题。当nginx worker进程数>1时且配置文件中打开accept_mutex时,这个标志置为1
if (ngx_use_accept_mutex)
{
//ngx_accept_disabled表示此时满负荷,没必要再处理新连接了,nginx.conf配置了每一个nginx worker进程能够处理的最大连接数,当达到最大数的7/8时,ngx_accept_disabled为正,说明本nginx worker进程非常繁忙,将不再去处理新连接,这也是个简单的负载均衡
if (ngx_accept_disabled > 0)
{
ngx_accept_disabled--;
}
else