我们知道,nginx接受连接请求的过程,配置文件中设置
events {
accept_mutex off;
}
让我们看看accept_mutex的意义:当一个新连接到达时,如果激活了accept_mutex,那么多个Worker将以串行方式来处理,其中有一个Worker会被唤醒,其他的Worker继续保持休眠状态;如果没有激活accept_mutex,那么所有的Worker都会被唤醒,不过只有一个Worker能获取新连接,其它的Worker会重新进入休眠状态,这就是「[惊群问题](http://en.wikipedia.org/wiki/Thundering_herd_problem)」。
Nginx缺省激活了accept_mutex,也就是说不会有惊群问题。对于惊群,如果唤醒的进程数量相对比较庞大,惊群会引起性能的损失。但类似于nginx这种一般只启动跟cpu核心数差不多的进程数。关闭accept_mutex或许是更好的选择。
我们来看看避免惊群的代码实现。
ngx_event.c
//是否使用accept互斥体。accept mutex的作用就是避免惊群,同时实现负载均衡
if (ngx_use_accept_mutex) {
if (ngx_accept_disabled > 0) { //大于0说明该进程接收的连接过多,放弃一次争抢accept mutex的机会
ngx_accept_disabled--;
} else {
if (ngx_trylock_accept_mutex(cycle) == NGX_ERROR) {
return;
}
if (ngx_accept_mutex_held) {
flags |= NGX_POST_EVENTS; //这个标志是将所有产生的事件放入到一个队列中。等释放锁以后再慢慢来处理事件。
} else {
if (timer == NGX_TIMER_INFINITE
|| timer > ngx_accept_mutex_delay) //设置最长延迟多久,再次去争抢锁
{
timer = ngx_accept_mutex_delay;
}
}
}
进程间通信采用共享内存。mmap