nginx对惊群效应的处理方式

惊群效应

惊群效应是指多个进程在监听等待一个端口时,如果一个事件到来,会唤起所有进程。但是最终只有一个进程获得该事件处理,其他进程获取事件失败后又继续进入到等待状态中,造成资源浪费。

nginx的处理方式

方式:Nginx中规定同一时刻只能有唯一一个的worker进程监听Web端口,此时新连接事件只能唤醒唯一正在监听端口的worker进程 。

也就是有一把互斥锁,每个进程中都尝试获得这把锁,争用监听套接口的监控权,如果获取成功将监听socket加入wait集合中,并设置超时等待连接到来,没有获得所的进程则将监听socket从wait集合去除。

同时还有后端的负载均衡策略。

1
2
# 最大连接数/8 - 空闲连接数 得到一个负数
ngx_accept_disabled = ngx_cycle->connection_n / 8 - ngx_cycle->free_connection_n;

当 ngx_accept_disabled 为正数,也就是当进程的空闲连接数小于1/8、活动连接数大于可承载连接数的7/8时, 将会停止去尝试获取互斥锁,并且ngx_accept_disabled会自减1。

  • 如果在处理新建连接事件的过程中,在监听套接字接口上又来了新的请求,当前进程只处理已缓存的事件,新的请求将被阻塞在监听套接字接口上,并且监听套接字接口是以水平方式加入到事件监控机制里的,所以等到下一轮被哪个进程争取到锁并加在事件监控机制里时才会触发而被抓取出来。

  • 在进程处理事件时,只是把锁释放了,而没有将监听套接字接口从事件监控机制里删除,所以当处理缓存事件过程中,互斥锁可能会被另外一个进程争抢到并把所有监听套接字接口加入到它的事件监控机制里。因此严格来说,在同一时刻,监听套接字可能被多个进程拥有,但是,在同一时刻,监听套接口只可能被一个进程监控,因此在进程处理完缓存事件之后去争抢锁,发现锁被其他进程占用而争抢失败,会把所有监听套接口从自身的事件监控机制删除,然后才进行事件监控。在同一时刻,监听套接口只可能被一个进程监控,所以受到惊群的影响。