tcp的网络惊群问题

  1. SO_REUSEPORT 可以解决epoll的惊群问题

但是,现在的 TCP Server,一般都是 多进程+多路IO复用(epoll) 的并发模型,比如我们常用的 nginx 。如果使用 epoll 去监听 accept socket fd 的读事件,当有新连接建立时,所有进程都会被触发。因为由于 fork 文件描述符继承的缘故,所有进程中的 accept socket fd 是相同的。惊群效应依然存在。nginx 也必然存在这个问题,nginx 为了解决问题,并且保证各个 worker 之前 accept 连接数的均衡,费了很大的力气。

有了 SO_REUSEPORT ,解决 多进程+多路IO复用(epoll) 并发模型 accept 惊群问题,就简单、高效很多。我们不需要通过 fork 的形式,让多进程监听同一个端口。只需要在各个进程中, 独自的 监听指定的端口,当然在监听前,我们需要为监听 socket 指定 SO_REUSEPORT ,否则会报错啦。由于没有采用 fork 的形式,各个进程中的 accept socket fd 不一样,加之有新连接建立时,内核只会唤醒一个进程来 accept,并且保证唤醒的 均衡性,因此使用 epoll 监听读事件,就不会触发所有啦。也有牛人为 nginx 提了 patch ,使用 SO_REUSEPORT 来杜绝 accept 惊群,并且还能够保证 worker 之间的均衡性哦。
泽民博客 | Jekyll theme

  1. Accept 就是bio。对poll/epoll/select都是是用来实现多路复用的,都不是bio

  2. linux 惊群问题

关注这块逻辑:

epoll_create()在Fork之前还是之后,有神马区别呢?

Fork之前epoll_create的话,所有进程共享一个epoll红黑数。

如果我们只需要处理accept事件的话,貌似世界一片美好了。但是,epoll并不是只处理accept事件,accept后续的读写事件都需要处理,还有定时或者信号事件。

当连接到来时,我们需要选择一个进程来accept,这个时候,任何一个accept都是可以的。当连接建立以后,后续的读写事件,却与进程有了关联。一个请求与a进程建立连接后,后续的读写也应该由a进程来做。

当读写事件发生时,应该通知哪个进程呢?Epoll并不知道,因此,事件有可能错误通知另一个进程,这是不对的。实验中观察到了这种现象

  1. epoll和惊群

比较下EPOLLEXCLUSIVE 和 SO_REUSEPORT

EPOLLEXCLUSIVE 和 SO_REUSEPORT 都是在内核层面将连接分到多个worker,解决了epoll下的惊群,SO_REUSEPORT 会更均衡一些,EPOLLEXCLUSIVE在压力不大的时候会导致连接总是在少数几个worker上(但这个不会产生任何不利影响)。 SO_REUSEPORT在最坏的情况下会导致一个worker即使Hang了,OS也依然会派连接过去,这是非常致命的,所以4.5内核引入了 EPOLLEXCLUSIVE(总是给闲置等待队列的第一个worker派连接)

探索惊群 ⑤ - nginx - NGX_EXCLUSIVE_EVENT

Nginx 是如何解决惊群效应的? | LinkinStar's Blog

nginx默认在linux支持的情况下,支持EPOLLEXCLUSIVE能力。也支持手动修改配置支持SO_REUSEPORT能力

相关推荐
代码游侠2 小时前
学习笔记——设备树基础
linux·运维·开发语言·单片机·算法
Gary Studio2 小时前
rk芯片驱动编写
linux·学习
mango_mangojuice2 小时前
Linux学习笔记(make/Makefile)1.23
java·linux·前端·笔记·学习
Harvey9032 小时前
通过 Helm 部署 Nginx 应用的完整标准化步骤
linux·运维·nginx·k8s
ManThink Technology2 小时前
如何使用EBHelper 简化EdgeBus的代码编写?
java·前端·网络
珠海西格电力科技3 小时前
微电网能量平衡理论的实现条件在不同场景下有哪些差异?
运维·服务器·网络·人工智能·云计算·智慧城市
QT.qtqtqtqtqt3 小时前
未授权访问漏洞
网络·安全·web安全
A星空1233 小时前
一、Linux嵌入式的I2C驱动开发
linux·c++·驱动开发·i2c
释怀不想释怀3 小时前
Linux环境变量
linux·运维·服务器
zzzsde3 小时前
【Linux】进程(4):进程优先级&&调度队列
linux·运维·服务器