Nginx的惊群问题

Posted 网络小菜鸟

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Nginx的惊群问题相关的知识,希望对你有一定的参考价值。

什么是惊群?


nginx早期的版本中,多个worker进程监听相同端口,这样多个进程在accept新连接时会有争抢。假设现在所有worker进程都在休眠等待新连接的到来,这时又一个用户向服务器发起了连接,内核在收到TCPSYN包时,会激活所有的在等待的worker进程(epoll机制),但是最终只有一个worker进程可以成功accept,而其他所有的worker进程都将accept失败,但是所有的worker进程都被惊醒。这就是很形象的“惊群”效应。惊群效应占用了大量的资源,引发了不必要的进程切换,毕竟只有一个worker被唤醒是有价值的,其他的都是多余的。

 就像你扔一条骨头给一群狗一样,所有狗都跑过来抢,但是只有一个抢到了,其他都白跑了。


Nginx怎么解决惊群的?


Nginxngx_event_process_init中引入了这个变量:ngx_use_accept_mutex

nginx就使用了这个锁来控制当前进程是否有权限将需要监听的端口添加到当前进程的epoll句柄中,也就是说,只有获取锁的进程才会监听目标端口。通过这种方式,就保证了每次事件发生时,只有一个worker进程会被触发。

Nginx的惊群问题


但是,各个worker进程在锁竞争这里会有比较大的消耗,那有没有更好的方式呢?

答案是肯定的,就是SO_REUSEPORT选项

在未开启 SO_REUSEPORT 时,由一个监听 socket 将新接收的连接请求交给各个 worker 处理。

 

Nginx的惊群问题


在使用 SO_REUSEPORT 后,多个进程可以同时监听同一个 IP:Port ,然后由内核决定将新连接发送给那个进程,显然会降低各个 worker 接收新连接时锁竞争。

 




以上是关于Nginx的惊群问题的主要内容,如果未能解决你的问题,请参考以下文章

Nginx中的惊群现象解决方法

Nginx源码分析 - 主流程篇 - 多进程的惊群和进程负载均衡处理

nginx惊群问题的解决方式

多线程环境下的惊群现象

Redis 利用锁机制来防止缓存过期产生的惊群现象-转载自 http://my.oschina.net/u/1156660/blog/360552

epoll_wait惊群问题