nginx系列第七篇:结合nginx讨论“惊群”问题

news2025/7/9 4:24:58

目录

1.什么是惊群

2.linux下socket通信之accept"惊群"现象

3.select/poll/epoll"惊群"现象

4.nginx中的惊群处理


1.什么是惊群

"惊群"是多个进程(线程)阻塞在某个系统调用上等待事件触发,当事件触发后,这些睡眠的进程(线程)会被同时唤醒,多个进程(线程)从阻塞的系统调用返回。"惊群"效率低下,
大量的CPU时间浪费在被唤醒发现无事可做,然后又继续睡眠的反复切换上。

2.linux下socket通信之accept"惊群"现象

        socket网络通信中,网络数据包的接收是异步进行的,数据包到来的处理分为两部分:
一是网卡通知数据包到来,中断协议栈收包。
二是协议栈将数据包填充socket的接收队列,通知应用程序有数据可读。
应用程序是通过socket和协议栈交互的,socket是应用程序和协议栈之间联系的桥梁,socket是两者之间的接口,
当数据包到达协议栈的时候,发生下面两个过程:
(1)协议栈将数据包放入socket的接收缓冲区队列,并通知持有该socket的应用程序;
(2)持有该socket的应用程序响应通知事件,将数据包从socket的接收缓冲区队列中取出

此处引用别出的一个图进行说明:

    对于高性能的服务器而言,为了利用多 CPU 核的优势,基本上都采用多个进程(线程)的方式同时accept在一个listen socket上。多个进程(线程)阻塞在accept调用上,在协议栈将client的请求socket放入listen socket的accept队列的时候,是要唤醒一个进程还是全部进程来处理呢?
linux内核通过睡眠队列来组织所有等待某个事件的task,而 wakeup 机制则可以异步唤醒整个睡眠队列上的 task,wakeup 逻辑在唤醒睡眠队列时,会遍历该队列链表上的每一个节点,调用每一个节点的 callback,从而唤醒睡眠队列上的每个 task。这样,在一个 connect 到达这个 lisent socket 的时候,内核会唤醒所有睡眠在 accept 队列上的 task。N 个 task 进程(线程)同时从 accept 返回,但是,只有一个 task 返回这个 connect 的 fd,其他 task 都返回-1(EAGAIN)。这是典型的 accept"惊群"现象。这个是 linux 上困扰了大家很长时间的一个经典问题,在 linux2.6(又说是2.4.1)以后的内核中得到彻底的解决,通过添加了一个 WQ_FLAG_EXCLUSIVE 标记告诉内核进行排他性的唤醒,即唤醒一个进程后即退出唤醒的过。用户进程 task 对 listen socket 进行 accept 操作,如果这个时候如果没有新的 connect 请求过来,用户进程 task 会阻塞睡眠在 listent fd 的睡眠队列上。这个时候,用户进程 Task 会被设置 WQ_FLAG_EXCLUSIVE 标志位,并加入到 listen socket 的睡眠队列尾部(这里要确保所有不带 WQ_FLAG_EXCLUSIVE 标志位的 non-exclusive waiters 排在带 WQ_FLAG_EXCLUSIVE 标志位的 exclusive waiters 前面)。根据前面的唤醒逻辑,一个新的 connect 到来,内核只会唤醒一个用户进程 task 就会退出唤醒过程,从而不存在了"惊群"现象。

3.select/poll/epoll"惊群"现象

        linux系统内核优化以后,accept系统调用已经不存在"惊群"现象。但是在实际服务端开发中,我们会存在另外一种惊群问题,通常一个服务端有很多网络IO需要处理,为了提高server的并发能力,不会让server阻塞在accept调用上,一般会使用 select/poll/epoll I/O 多路复用技术,同时为了充分利用多核CPU的有害,服务器上会起多个进程(线程)同时提供服务。因此在某一时刻多个进程(线程)阻塞在 select/poll/epoll_wait 系统调用上,当一个请求上来的时候,多个进程都会被 select/poll/epoll_wait 唤醒去 accept,然而只有一个进程(线程)accept 成功,其他进程(线程accept失败,然后重新阻塞在select/poll/epoll_wait系统调用上。因此尽管 accept 不存在"惊群"了,但是我们出现了另外的"惊群"。针对这个问题(只让一个进程(线程)去监听 listen socket 的可读事件),我们可以看一些nginx是如何处理惊群的。

4.nginx中的惊群处理

       nginx master不会接受任何请求,所有的连接都在worker中处理。nginx所有worker并不能同时accept多个新连接,nginx实现了一个叫accept锁的东西,同一时刻只有一个worker能够获取到这个accept锁,只有获取到锁的这个worker才能够accept新连接。代码实现如下:

      当 ngx_use_accept_mutex 为 1 的时候(当 nginx worker 进程数>1 时且配置文件中打开 accept_mutex 时,这个标志置为 1),表示要规避 listen fd"惊群"。nginx 的 worker 进程在进行 event 模块的初始化的时候, core event 模块的 process_init 函数中(ngx_event_process_init)将 listen fd 加入到 epoll 中并监听其 READ 事件。

       nginx 通过一次仅允许一个进程将 listen fd 放入自己的 epoll 来监听其 READ 事件的方式来达到 listen fd"惊群"避免。然而做好这一点并不容易,作为一个高性能 web 服务器,需要尽量避免阻塞,并且要很好平衡各个工作 worker 的请求,避免饿死情况。

(1)避免新请求不能及时得到处理的饿死现象。worker进程在抢夺到accept权限,加锁成功的时候,要将事件的处理delay到释放锁后在处理(为什么ngx_posted_accept_events队列上的事件处理不需要延迟呢? 因为ngx_posted_accept_events上的事件就是listen fd的可读事件,本来就是我抢到的accept权限,还没accept就释放锁,这个时候被别人抢走了怎么办呢?)。否则,获得锁的工作worker由于在处理一个耗时事件,这个时候大量请求过来,其他worker进程空闲却没有处理权限在干着急的等着。

(2)避免总是某个worker进程抢到锁的现象。大量请求被同一个进程抢到,而其他worker进程却很清闲。 nginx有个简单的负载均衡,ngx_accept_disabled表示此时满负荷程度,没必要再处理新连接了,nginx.conf配置了每个worker进程能够处理的最大连接数,当达到最大数的7/8时,ngx_accept_disabled为正,说明本nginx worker进程非常繁忙,将不再去处理新连接。每次要进行抢夺accept权限的时候,如果ngx_accept_disabled大于0,则递减1,不进行抢夺逻辑。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/618909.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

数位dp训练笔记

依稀还记得去年寒假的时候对数位dp的恐惧达到了顶峰,打死也不想做一题,也是怎么学都学不会,甚至板子也只是真的去网上copy了一份,自己也都不理解。(羞愧) 这个状态持续了一年多(羞愧羞愧&#…

Windows操作/文件/设置/DOS 记录

目录 1.系统操作 1.环境变量 2.文件夹操作 1.显示隐藏文件夹 3.DOS窗口 1.DOS窗口中docker切换管理员root /]#身份: docker run -it centos​编辑 4.文件操作 1.图片分辨率无损修改尺寸(例1280x800) 2.图片修改png/jpg文件后缀类型 1.系统操作 1.…

Python 语句

文章目录 一、条件语句1、顺序语句2、条件语句3、缩进和代码块4、条件语句练习5、空语句 二、循环语句1、while2、for3、break和continue 一、条件语句 1、顺序语句 从上到下依次执行 2、条件语句 Python中使用if else关键字表示条件语句. ①if if expression:do_somethi…

PCB板的Mark点设计对SMT重要性

Mark点也称光学点、基准点,是电路板元器件组装中,PCBA应用于自动贴片机上的位置识别点。 Mark点的选用,直接影响到自动贴片机的贴片效率,因此在设计时,需要设计好Mark点以及其在板内的位置。 Mark点的设计 1、布局位…

String s = new String(“xyz“) 创建了几个对象?

这个问题相信每个学习 java 的同学都不陌生,作为一个经典的面试题,到现在工作这么多年了我真是认为挺操蛋的一个问题,在网上到现在你仍然可以看见很多讨论这个问题的人,其中不乏工作很多年的人都有争论,我认为还是有必…

GreatSQL删除分区慢的跟踪

GreatSQL删除分区慢的跟踪 背景 某业务系统,每天凌晨会删除分区表的一个分区(按天分区),耗时较久,从最开始的30秒,慢慢变为1分钟,影响到交易业务的正常进行。 在测试环境进行了模拟,复现了删除分区慢的情…

市场火爆!三大发展优势加速汽车零部件行业布局

当前,中国新能源汽车自主品牌崛起,为汽车零部件发展带来新机遇;有别于传统汽车零部件市场,新能源领域,主机厂标准提升,对数字化要求逐渐提高,汽车零部件企业的智能制造异常重要,企业…

二分类结局变量Logistic回归临床模型预测(二)——3. 单因素多因素logistic回归分析及三线表(三)

本节讲的是二分类结局变量的临床模型预测,与之前讲的Cox回归不同,https://lijingxian19961016.blog.csdn.net/article/details/124088364https://lijingxian19961016.blog.csdn.net/article/details/124088364https://lijingxian19961016.blog.csdn.net/article/details/1300…

1929-2022年全球站点的逐月最低气温(Shp\Excel\12000个站点)

气象数据是在各项研究中都经常使用的数据,气象指标包括气温、风速、降水、湿度等指标,其中又以气温指标最为常用!说到气温数据,最详细的气温数据是具体到气象监测站点的气温数据! 之前我们分享过1929-2022年全球气象站…

Qt学习之旅 -信号与槽

文章目录 点击关闭窗口自定义信号和槽自定义信号和槽解决重载问题信号和连接信号断开连接Qt4版本信号槽连接Lambda表达式 点击关闭窗口 connect(信号发送者,发送的具体信号,信号接收者,型号的处理(槽slot));这里自定义的MyPushButton与QPushButton别无二…

【NLP】KMP匹配算法

一、说明 KMP算法。也称为Knuth-Morris-Pratt字符串查找算法可在一个字符串S内查找一个词W的出现位置。一个词在不匹配时本身就包含足够的信息来确定下一个匹配可能的开始位置,此算法利用这一特性以避免重新检查先前配对的字符。将时间复杂度从O(M*N)降为O(N). 这个…

C++ Primer Plus 第三章习题

目录 复习题 1. 为什么C有多种整型? 2. 声明与下述描述相符的变量? 3. C 提供了什么措施来防止超出整型的范围? 4. 33L和33之间有什么区别? 5. 下面两条C语句是否等价? 6. 如何使用C来找出编码88表示的字符&…

又一个生物标志物ADMA被发现!可为OA治疗提供新方向!

文章标题:Metabolite asymmetric dimethylarginine (ADMA) functions as a destabilization enhancer of SOX9 mediated by DDAH1 in osteoarthriti 发表期刊:Science Advances 影响因子:14.95 作者单位:浙江大学医学院附属邵逸…

EasyUi03

1.无限极分类. 1.1无限极分类介绍. 1.1.1何为无限极分类. 无限极分类简单点说就是一个类别能够分多个子类,而后一个子类又能够分多个子类,就这样无限分下去,就好象 windows能够新建一个文件夹,而后在这个文件夹里又能够建一些文…

《嵌入式系统》知识总结12:SysTick定时器

SysTick定时器 系统时钟(SysTick) Corte-M3在内核中包含的简单定时器 • 该定时器的时钟源可以来自CM3内部时钟(FCLK),或CM3外部时钟(STCLK) • 在STM32微控制器中,SysTick的时钟源可…

平板触控笔哪款好用?电容笔牌子排行

现如今,电容笔越来越受欢迎,不少人在记笔记、学画画甚至是玩游戏的时候都会使用它。最近看到很多人问,iPad电容笔哪款好用?针对这个问题,我来给大家推荐四款公认好用的平替电容笔,一起来看看吧。 一、主动…

实验篇(7.2) 08. 通过安全隧道访问内网服务器 (FortiClient-IPsec) ❀ 远程访问

【简介】通过对SSL VPN与IPsec VPN的对比,我们知道SSL VPN是基于应用层的VPN,而IPsec VPN是基于网络层的VPN,IPsec VPN对所有的IP应用均透明。我们看看怎么用FortiClient实现IPsec VPN远程访问。 实验要求与环境 OldMei集团深圳总部部署了一台…

眼底图片解读(对比图!!!)

目录 1. 前言 2.常见眼底解析 (1) 黄斑变性 (2) 糖尿病视网膜病变 (3) 青光眼 (4) 视网膜血管阻塞 (5)视网膜裂孔和脱离 1. 前言 眼底图像是通过眼底摄影等技术获取的眼底部位的影像,可以提供关于眼睛健康和疾病的重要信息。以下是眼底图像中常见的信息和相关…

只见新人笑,不见旧人哭 ChatGPT淘汰了多少产品?快来了解!

ChatGPT作为目前世界上最先进的人工智能聊天工具,其GPT模型就是一种自然语言处理(NLP)模型,使用多层变换器(Transformer)来预测下一个单词的概率分布,通过训练在大型文本语料库上学习到的语言模…

chatgpt赋能python:Python自动运行教程:让你的工作更智能化

Python自动运行教程:让你的工作更智能化 Python是一种高级、解释型、面向对象的编程语言,被广泛应用于数据分析、机器学习和自动化任务等领域。除此之外,Python还能够实现自动化运行,让用户无需手动干预,从而减轻工作…