[转帖]探索惊群 ⑥ - 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队 ...
随机推荐
- flutter屏幕适配方案
使用MediaQuery和比例因子 优点:使用简单,可以处理大多数情况下的屏幕适配需求. 缺点:需要手动计算比例因子,并且随着UI元素变得更加复杂和层次化(例如多层次列表或动画效果),使用此方法可能会 ...
- WMTS地图服务每一层级分辨率
目录 1. 概述 2. 详论 2.1. Web墨卡托 2.2. 大地经纬度 3. 参考 1. 概述 WMTS地图服务每一层级的分辨率是多少?关于这个问题以前推算过,但总是忘记了.网上查询又是一堆废话, ...
- maven 实现pb的实时编译
<properties> <protobuf.version>3.15.7</protobuf.version></properties> <ex ...
- Karmada 结合 coreDNS 插件实现跨集群统一域名访问
本文分享自华为云社区<Karmada 结合 coreDNS 插件实现跨集群统一域名访问>,作者:云容器大未来 . 在多云与混合云越来越成为企业标配的今天,服务的部署和访问往往不在一个 K8 ...
- 【好书推荐】《Python黑魔法指南》-附高清PDF版
摘要:<Python 黑魔法手册.pdf >作者(明哥)是一个从事云计算多年的 Python 重度用户,它把自已多年的 Python 编码经验整理成小册子,没有长篇大论,半天就能全能掌握, ...
- 实践丨GaussDB(DWS)资源管理排队原理与问题定位
摘要:GaussDB(DWS)提供了资源管理功能,用户可以根据自身业务情况对资源进行划分,将资源按需划分成不同的资源池,不同资源池之间资源互相隔离. 本文分享自华为云社区<GaussDB(DWS ...
- 云小课|MRS基础原理之Oozie任务调度
阅识风云是华为云信息大咖,擅长将复杂信息多元化呈现,其出品的一张图(云图说).深入浅出的博文(云小课)或短视频(云视厅)总有一款能让您快速上手华为云.更多精彩内容请单击此处. 摘要:Oozie是一个基 ...
- 带你了解NB-IoT标准演进
摘要:本文将带大家详细了解NB-IoT标准演进与产业发展. 本文分享自华为云社区<一文带你了解NB-IoT标准演进与产业发展>,作者:万万万. 我们都知道,物联网的场景和手机.电脑在使用的 ...
- DevSecOps: CI/CD 流水线安全的最佳实践
上一篇文章我们了解了 IAST 及其优势.工具类型以及重要性. 本期文章将为你介绍 CI/CD 流水线安全的最佳实践. ✦ ✦ CI/CD 流水线是指由持续集成(Continuous Integrat ...
- 差点错过!火山引擎VeDI帮这家企业成功挖掘200余条商机
更多技术交流.求职机会,欢迎关注字节跳动数据平台微信公众号,回复[1]进入官方交流群 与个体消费市场临时性需求大.决策参与人少等情况不同,企业消费市场往往因为长线需求复杂.商品/服务的价格高.参与决策 ...