惊群可以参考:
“惊群”,看看nginx是怎么解决它的
1. 什么是惊群:
多线程/多进程(linux下线程进程也没多大区别)等待同一个socket事件,当这个事件发生时,这些线程/进程被同时唤醒,就是惊群。可以想见,效率很低下,许多进程被内核重新调度唤醒,同时去响应这一个事件,当然只有一个进程能处理事件成功,其他的进程在处理该事件失败后重新休眠(也有其他选择)。这种性能浪费现象就是惊群。
2. 惊群的历史
2.1 accept
阻塞接口,不会出现惊群了。
2.2 epoll_wait
的惊群问题在这个patch epoll: add EPOLLEXCLUSIVE flag 21 Jan 2016已经解决了,通过添加EPOLLEXCLUSIVE标志标识在唤醒时,只唤醒一个等待进程。
2.3 nginx方案
nginx是在epoll_wait支持EPOLLEXCLUSIVE标志之前出现的,所以是使用自己的方案解决的。
- 连接完成之后的IO事件
每个work进程都有自己的epoll,一个连接由一个worker进程完成accept并且其后续的IO都由本worker的epoll监听,所以不会出现惊群。 - accept
2.1 每个worker首先会获取进程锁,拿到锁之后才向自己的epoll中添加accept事件,其他未获得锁的worker的epoll中没有accept事件。简单了说,就是同一时刻只允许一个nginx worker在自己的epoll中处理监听句柄。
2.2 为什么不只使用一个进程accept?
只有一个进程accept在多核条件下会存在性能瓶颈。accept可能比较耗CPU,只有一个accept进程会存在限制。
2.3 连接的负载均衡
它的负载均衡也很简单,当达到最大connection的7/8时,本worker不会去试图拿accept锁,也不会去处理新连接,这样其他nginx worker进程就更有机会去处理监听句柄,建立新连接了。而且,由于timeout的设定,使得没有拿到锁的worker进程,去拿锁的频繁更高。
网友评论