Nginx惊群

Nginx采用的是多进程模型,master进程建立好需要listen的socket fd之后,然后fork出N个worker进程。如果所有worker进程同时监听这个fd的事件,当有新一个连接到来时,这些进程会被同时唤醒去处理事件——accept。但是只有一个进程的accept会成功,而其他进程都会失败,这样的现象叫做惊群,会极大影响Nginx的性能。

其实,linux2.6内核已经解决了accept系统调用本身的惊群问题了。如果在父进程中listen,然后fork出的所有子进程都accept这个fd。当新连接过来时,仅有一个子进程的accept会返回,其他子进程则继续阻塞在accept调用上。但是对于Nginx的epoll循环来说,这个问题依然存在,因为监听的socket依然会同时产生可读事件,把阻塞在epoll_wait上的所有worker全部唤醒。

Nginx中处理epoll时惊群问题的思路很简单,引入了一个互斥锁,worker进程谁拿到锁,谁才将accept的fd加入到epoll队列中,其他的子进程拿不到锁,会将fd从epoll队列中移除,新连接到来也就不会导致所有子进程的epoll_wait被唤醒返回。

在处理事件的函数ngx_process_events_and_timers中,worker会尝试获得accept_mutex锁,同一时刻只有一个worker可以获得这把互斥锁。如果一个worker拿到了锁,就把监听的fd加入epoll队列,并且置NGX_POST_EVENTS标志位,意思是会优先处理accept事件,把其他所有事件放在accept后延后处理,因为在处理完accept事件后worker就可以立刻释放互斥锁,这样尽量减少锁的占用时间。

在获取accept_mutex锁前还有一个负载均衡的逻辑,如果worker的当前活动连接数超过最大可承受连接数的7/8,则表示发生过载,不会去争取锁。

转载于:https://my.oschina.net/u/2940064/blog/757699

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值