[转帖]探索惊群 ⑥ - nginx - reuseport
https://wenfh2020.com/2021/10/12/thundering-herd-tcp-reuseport/
SO_REUSEPORT (reuseport) 是网络的一个选项设置,它能开启内核功能:网络链接分配 内核负载均衡。
该功能允许多个进程/线程 bind/listen 相同的 IP/PORT,提升了新链接的分配性能。
nginx 开启 reuseport 功能后,性能有立竿见影的提升,我们结合 tcp 协议分析 nginx 的 reuseport 功能。
reuseport 也是内核解决 惊群问题 的优秀方案。
每个进程可以 bind/listen 相同的 IP/PORT,相当于每个进程拥有独立的 listen socket 的完全队列,避免了共享 listen socket 的资源争抢,提升了并发的吞吐。
内核通过哈希算法,将新链接相对均衡地分配到各个开启了 reuseport 属性的进程,所以资源的负载均衡得到解决。
- 探索惊群 ①
- 探索惊群 ② - accept
- 探索惊群 ③ - nginx 惊群现象
- 探索惊群 ④ - nginx - accept_mutex
- 探索惊群 ⑤ - nginx - NGX_EXCLUSIVE_EVENT
- 探索惊群 ⑥ - nginx - reuseport(★)
- 探索惊群 ⑦ - 文件描述符透传
1. 概述
1.1. what
从下面这段英文提取一些关键信息:
SO_REUSEPORT 是网络的一个选项设置,它允许多个进程/线程 bind/listen 相同的 IP/PORT,在 TCP 的应用中,它是一个新链接分发的(内核)负载均衡功能,它提升了新链接的分配性能(针对 accept )。
1 |
Socket options |
注释文字来源 (链接需要FQ):socket(7) — Linux manual page
1.2. why
SO_REUSEPORT 功能解决了什么问题?我们先看看 2013 年 3.9+ 版本内核提交的这个 Linux 内核功能 补丁 的注释。
1 |
soreuseport: TCP/IPv4 implementation |
reuseport 选项主要解决了两个问题:
- (A 图)单个 listen socket 遇到的性能瓶颈。
- (B 图)单个 listen socket 多个线程同时 accept,但是多个线程资源分配不均。

其实它还解决了一个很重要的问题:
在 tcp 多线程场景中,(B 图)服务端如果所有新链接只保存在一个 listen socket 的 全链接队列 中,那么多个线程去这个队列里获取(accept)新的链接,势必会出现多个线程对一个公共资源的争抢,争抢过程中,大量资源的损耗。
而(C 图)有多个 listener 共同 bind/listen 相同的 IP/PORT,也就是说每个进程/线程有一个独立的 listener,相当于每个进程/线程独享一个 listener 的全链接队列,不需要多个进程/线程竞争某个公共资源,能充分利用多核,减少竞争的资源消耗,效率自然提高了。
1.3. how
SO_REUSEPORT 功能使用,可以通过网络选项进行设置,在 bind 前面设置即可,使用比较简单。
1 |
int fd, reuse = 1; |
2. 原理
TCP 客户端链接服务端,第一次握手,服务端被动收到第一次握手 SYN 包,内核就通过哈希算法,将客户端的链接分派到内核半链接队列,三次握手成功后,再将这个链接从半链接队列移动到某个 listener 的全链接队列中,提供 accept 获取。
- 三次握手流程。

图片来源:TCP 三次握手(内核)
- 服务端被动第一次握手,查找合适的 listener,详看源码(Linux 5.0.1)。

1 |
/* include/net/inet_hashtables.h */ |
3. nginx
2013 年 Linux 内核添加了 reuseport 功能后,nginx 在 2015 年,1.9.1 版本也增加对应功能的支持,nginx 开启 reuseport 功能后,性能是原来的 2-3 倍,效果可谓立竿见影!
详细请参考 nginx 官方文档:Socket Sharding in NGINX Release 1.9.1
接下来我们看看 nginx 是如何支持 reuseport 的。
3.1. 开启 SO_REUSEPORT
修改 nginx 配置,在 nginx.conf 里,listen 关键字后面添加 ‘reuseport’。
1 |
# nginx.conf |
3.2. 工作流程
启动测试 nginx,1 master / 4 workers,监听 80 端口。
3.2.1. 进程
- 父子进程。
1 |
# ps -ef | grep nginx |
父子进程 LISTEN 80 端口情况。
因为配置文件设置了
worker_processes 4需要启动 4 个子进程, nginx 进程发现配置文件关键字 listen 后添加了 reuseport 关键字,那么主进程先创建 4 个 socket 并设置 SO_REUSEPORT 选项,然后进行 bind 和 listen。当 fork 子进程时,子进程拷贝了父进程的这 4 个 socket,所以你看到每个子进程都有相同 LISTEN 的 socket fd(6,7,8,9)。
1 |
# lsof -i:80 | grep nginx |
3.2.2. 网络初始流程
nginx 是多进程模型,Linux 环境下一般使用 epoll 事件驱动。

- strace 监控 nginx 进程的系统调用流程。
1 |
# strace -f -s 512 -o /tmp/nginx.log /usr/local/nginx/sbin/nginx |
- 分析总结一下 strace 采集的系统调用日志。
1 |
# 如果有 N 个子进程就创建 N 个 socket 并对其设置,绑定地址和监听端口。 |
- 源码函数调用层次。
1 |
# 函数调用层次关系。 |
4. 参考
- 《Linux 内核源代码情景分析》
- 多个进程绑定相同端口的实现分析[Google Patch]
- 【优化】nginx启用reuseport
- Linux TCP SO_REUSEPORT — Usage and implementation
- 再谈Linux epoll惊群问题的原因和解决方案
- [epoll 源码走读] epoll 实现原理
- socket(7) — Linux manual page
- Socket Sharding in NGINX Release 1.9.1
- Linux 网络层收发包流程及 Netfilter 框架浅析
- Why does one NGINX worker take all the load?
- 深入浅出 Linux 惊群:现象、原因和解决方案
- Linux 4.6内核对TCP REUSEPORT的优化
- [内核源码] 网络协议栈 listen (tcp)
- 本文作者: wenfh2020
- 本文链接: https://wenfh2020.com/2021/10/12/thundering-herd-tcp-reuseport/
- 版权声明: 本文可以自由拷贝,转载,请注明出处,谢谢!
[转帖]探索惊群 ⑥ - nginx - reuseport的更多相关文章
- NGINX怎样处理惊群的
写在前面 写NGINX系列的随笔,一来总结学到的东西,二来记录下疑惑的地方,在接下来的学习过程中去解决疑惑. 也希望同样对NGINX感兴趣的朋友能够解答我的疑惑,或者共同探讨研究. 整个NGINX系列 ...
- “惊群”,看看nginx是怎么解决它的
在说nginx前,先来看看什么是“惊群”?简单说来,多线程/多进程(linux下线程进程也没多大区别)等待同一个socket事件,当这个事件发生时,这些线程/进程被同时唤醒,就是惊群.可以想见,效率很 ...
- Nginx学习之一-惊群现象
惊群问题(thundering herd)的产生 在建立连接的时候,Nginx处于充分发挥多核CPU架构性能的考虑,使用了多个worker子进程监听相同端口的设计,这样多个子进程在accept建立新连 ...
- Nginx惊群处理
惊群:是指在多线程/多进程中,当有一个客户端发生链接请求时,多线程/多进程都被唤醒,然后只仅仅有一个进程/线程处理成功,其他进程/线程还是回到睡眠状态,这种现象就是惊群. 惊群是经常发生现在serve ...
- 【转载】“惊群”,看看nginx是怎么解决它的
原文:http://blog.csdn.net/russell_tao/article/details/7204260 在说nginx前,先来看看什么是“惊群”?简单说来,多线程/多进程(linux下 ...
- Nginx中的惊群现象解决方法
*什么是惊群现象?Nginx中用了什么方法来避免这种问题的发生?本篇就解决这两个问题...→_→* 惊群现象的定义与危害 在Nginx中,每一个worker进程都是由master进程fork出来的.m ...
- 【Nginx】惊群问题
转自:江南烟雨 惊群问题的产生 在建立连接的时候,Nginx处于充分发挥多核CPU架构性能的考虑,使用了多个worker子进程监听相同端口的设计,这样多个子进程在accept建立新连接时会有争抢,这会 ...
- Nginx模型 & 惊群问题
这篇写的不错 http://www.cnblogs.com/linguoguo/p/5511293.html Nginx为啥性能高-多进程异步IO模型 1. 对于每个worker进程来说,独立的进程, ...
- Nginx惊群问题
Nginx惊群问题 "惊群"概念 所谓惊群,可以用一个简单的比喻来说明: 一群等待食物的鸽子,当饲养员扔下一粒谷物时,所有鸽子都会去争抢,但只有少数的鸽子能够抢到食物, 大部分鸽子 ...
- nginx&http 第三章 惊群
惊群:概念就不解释了. 直接说正题:惊群问题一般出现在那些web服务器上,Linux系统有个经典的accept惊群问题,这个问题现在已经在内核曾经得以解决,具体来讲就是当有新的连接进入到accept队 ...
随机推荐
- Python 潮流周刊第 35 期(摘要)
本周刊由 Python猫 出品,精心筛选国内外的 250+ 信息源,为你挑选最值得分享的文章.教程.开源项目.软件工具.播客和视频.热门话题等内容.愿景:帮助所有读者精进 Python 技术,并增长职 ...
- Ynoi
P4688 [Ynoi2016] 掉进兔子洞 序列,静态,求三个区间的可重集的交的大小,离线,\(n,Q\le 10^5\),3s,500MB 缺乏性质 \(\rightarrow\) bitset ...
- C++ 惯用法之 RAII
RAII(Resource Acquisition Is Initialization)资源获取即初始化,是 C++ 中最基本.应用最广范的惯用法(idiom)之一. RAII 的基本思想是通过构造/ ...
- Spring Cloud Eureka 服务注册中心怎么配置
「Spring Cloud Eureka 入门系列」 Spring Cloud Eureka 入门 (一)服务注册中心详解 Spring Cloud Eureka 入门 (二)服务提供者详解 Spri ...
- 基于AI的架构优化:创新数据集构造法提升Feature envy坏味道检测与重构准确率
本文分享自华为云社区<华为云基于AI实现架构坏味道重构取得业界突破,相应文章已被软工顶会FSE 2023收录>,作者: 华为云软件分析Lab. 基于AI技术实现架构坏味道检测与重构建议是当 ...
- 论文复现丨基于ModelArts进行图像风格化绘画
摘要:这个 notebook 基于论文「Stylized Neural Painting, arXiv:2011.08114.」提供了最基本的「图片生成绘画」变换的可复现例子. 本文分享自华为云社区& ...
- 查看Windows系统 重启时间
查看Windows系统 重启时间 CMD 命令 systeminfo 事件查看器 筛选:1074 6005: 开机时间.6006:关机时间
- Chrome 英文翻译插件,沙拉查词
下载: https://pan.baidu.com/s/1VRaZzKgyPKc0Qt6Gufk3yw 提取码: chbm 下载: https://pan.baidu.com/s/1VRaZzKgyP ...
- ES6常用知识学习札记
转载请注明出处 原文连接 http://blog.huanghanlian.com/article/5c7aa6c7bf3acc0864870f9d es6 是什么 首先弄明白ECMA和js的关系.E ...
- 基于rest_framework的ModelViewSet类编写登录视图和认证视图
背景:看了博主一抹浅笑的rest_framework认证模板,发现登录视图函数是基于APIView类封装. 优化:使用ModelViewSet类通过重写create方法编写登录函数. 环境:既然接触到 ...