Nginx 惊群问题

本文探讨了Nginx中使用SO_REUSEPORT可能导致的偶发性卡顿问题,重点介绍了惊群现象如何在epoll机制下出现,以及REUSEPORT选项如何通过限制每个worker的epoll对象等待队列来避免惊群。
摘要由CSDN通过智能技术生成

1、Nginx reuseport导致偶发性卡顿
2、Why does one NGINX worker take all the load?
3、The SO_REUSEPORT socket option
开启so_reuseport的多个tcp/udp套接字可以绑定相同的套接字地址。
4、 SO_REUSEPORT man-page
5、soreuseport: Bind multiple sockets to the same port
6、惊群解决EPOLLEXCLUSIVE、REUSEPORT方案 .
在每个worker进程有各自的epoll对象,并监视同一个监听套接字上事件的情况下。当该监听套接字返回事件时, EPOLLEXCLUSIVE会找到并唤醒第一个处于休眠状态的worker进程来处理该事件。
EPOLLEXCLUSIVE惊群:当监听套接字上有读事件时遍历该套接字的等待队列项,调用每一个等待队列项的ep_poll_callback,ep_poll_callback会首先把事件添加到该epoll的就绪链表,但是当该epoll对应的worker进程处于运行状态时,会继续遍历等待队列项,直到找到一个休眠状态的worker进程。当唤醒该worker进程时,该事件可能已经被前面的处于运行状态的worker进程处理。
7、 再谈Linux epoll惊群问题的原因和reuseport解决方案
8、EPOLLEXCLUSIVE man-page
9、EPOLLEXCLUSIVE 条件:Linux 4.5, glibc 2.24

10、接收数据时有关的等待队列项
在同步阻塞模式下,socket的等待队列项是

wait_queue_t name = {
	.private = current, # 当前进程ID
	.func = autoremove_wake_function 
}

当socket接收队列没有数据(足够)可读时,添加一个等待队列项到socket的等待队列中,并阻塞当前进程;当socket接收队列有数据可读时,调用autoremove_wake_function唤醒等待队列项中的进程来接收数据。

在epoll模式下,socket的等待队列项是

wait_queue_t {
	.flag = 0
	.private = NULL
	.func = ep_poll_callback
}

当调用epoll_ctl 把socket上事件注册到epoll时,把该等待队列项添加到socket的等待队列,由于该等待队列项的作用不是唤醒当前进程,所有private为NULL;当socket接收队列有数据可读时,调用ep_poll_callback找到相应的epitem和epoll对象,把epitem添加到epoll对象的就绪链表中,epoll_wait返回读事件给用户进程。
eventpoll对象的等待队列项是

wait_queue_t {
	.flags = WQ_FLAG_EXCLUSIVE
	.private = current #当前进程
	.func = default_wake_function
}

当epoll_wait没有返回事件时,添加一个等待队列项到eventpoll对象的等待队列中,并阻塞当前进程。当socket接收队列有数据可读时,调用default_wake_function唤醒进程,从epoll_wait阻塞时暂停的代码处继续执行。
11、reuseport解决Nginx惊群问题
Nginx每个worker进程都有一个epoll对象,每一个epoll对象的等待队列里只会有一个等待队列项,对应相应的阻塞worker进程。
当没有开启so_reuseport时,对于一个端口所有的worker进程共用一个监听套接字,每一个worker进程会把该监听套接字上的读事件注册到自己的epoll中,该监听套接字的等待队列也会有n(进程数量,每注册一次该套接字上的读事件,添加一个等待队列项)个等待队列项。当该监听套接字上有新连接来时,会遍历套接字的等待队列项,找到每一个进程监视的epoll,epoll会唤醒相应的worker进程,从而产生惊群问题。
当开启so_reuseport后,对于一个端口每个worker进程都有一个监听套接字,每个监听套接字的等待队列只有一个等待队列项。当有新连接来时,内核会通过四元组hash调度其中一个监听套接字来建立连接,只有一个相应的worker进程被唤醒。
12、udp套接字开了reuseport后,同一个会话的报文只会(由内核通过四元组hash调度)打到一个特定的udp套接字。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值