Nginx 是如何解决惊群效应的?

什么是惊群效应?

第一次听到的这个名词的时候觉得很是有趣,不知道是个什么意思,总觉得又是奇怪的中文翻译导致的。

复杂的说(来源于网络)TLDR;

惊群效应(thundering herd)是指多进程(多线程)在同时阻塞等待同一个事件的时候(休眠状态),如果等待的这个事件发生,那么他就会唤醒等待的所有进程(或者线程),但是最终却只能有一个进程(线程)获得这个时间的“控制权”,对该事件进行处理,而其他进程(线程)获取“控制权”失败,只能重新进入休眠状态,这种现象和性能浪费就叫做惊群效应。

简单的讲(我的大白话)

有一道雷打下来,把很多人都吵醒了,但只有其中一个人去收衣服了。也就是:有一个请求过来了,把很多进程都唤醒了,但只有其中一个能最终处理。

原因&问题

说起来其实也简单,多数时候为了提高应用的请求处理能力,会使用多进程(多线程)去监听请求,当请求来时,因为都有能力处理,所以就都被唤醒了。

而问题就是,最终还是只能有一个进程能来处理。当请求多了,不停地唤醒、休眠、唤醒、休眠,做了很多的无用功,上下文切换又累,对吧。那怎么解决这个问题呢?下面就是今天要看的重点,我们看看 nginx 是如何解决这个问题的。

Nginx 架构

第一点我们需要了解 nginx 大致的架构是怎么样的。nginx 将进程分为 master 和 worker 两类,非常常见的一种 M-S 策略,也就是 master 负责统筹管理 worker,当然它也负责如:启动、读取配置文件,监听处理各种信号等工作。

但是,第一个要注意的问题就出现了,master 的工作有且只有这些,对于请求来说它是不管的,就如同图中所示,请求是直接被 worker 处理的。如此一来,请求应该被哪个 worker 处理呢?worker 内部又是如何处理请求的呢?

Nginx 使用 epoll

接下来我们就要知道 nginx 是如何使用 epoll 来处理请求的。下面可能会涉及到一些源码的内容,但不用担心,你不需要全部理解,只需要知道它们的作用就可以了。顺便我会简单描述一下我是如何去找到这些源码的位置的。

Master 的工作

其实 Master 并不是毫无作为,至少端口是它来占的。https://github.com/nginx/nginx/blob/b489ba83e9be446923facfe1a2fe392be3095d1f/src/core/ngx_connection.c#L407C13-L407C13

ngx_open_listening_sockets(ngx_cycle_t *cycle)
{.....for (i = 0; i < cycle->listening.nelts; i++) {.....if (bind(s, ls[i].sockaddr, ls[i].socklen) == -1) {if (listen(s, ls[i].backlog) == -1) {
}

那么,根据我们 nginx.conf 的配置文件,看需要监听哪个端口,于是就去 bind 的了,这里没问题。

【发现源码】这里我是直接在代码里面搜 bind 方法去找的,因为我知道,不管你怎么样,你总是要绑定端口的

然后是创建 worker 的,虽不起眼,但很关键。https://github.com/nginx/nginx/blob/b489ba83e9be446923facfe1a2fe392be3095d1f/src/os/unix/ngx_process.c#L186

ngx_spawn_process(ngx_cycle_t *cycle, ngx_spawn_proc_pt proc, void *data,char *name, ngx_int_t respawn)
{....pid = fork();

【发现源码】这里我直接搜 fork,整个项目里面需要 fork 的情况只有两个地方,很快就找到了 worker

由于是 fork 创建的,也就是复制了一份 task_struct 结构。所以 master 的几乎全部它都有。

Worker 的工作

Nginx 有一个分模块的思想,它将不同功能分成了不同的模块,而 epoll 自然就是在 ngx_epoll_module.c 中了

https://github.com/nginx/nginx/blob/b489ba83e9be446923facfe1a2fe392be3095d1f/src/event/modules/ngx_epoll_module.c#L330C23-L330C23

ngx_epoll_init(ngx_cycle_t *cycle, ngx_msec_t timer)
{ngx_epoll_conf_t  *epcf;epcf = ngx_event_get_conf(cycle->conf_ctx, ngx_epoll_module);if (ep == -1) {ep = epoll_create(cycle->connection_n / 2);

其他不重要,就连 epoll_ctl 和 epoll_wait 也不重要了,这里你需要知道的就是,从调用链路来看,是 worker 创建的 epoll 对象,也就是每个 worker 都有自己的 epoll 对象,而监听的sokcet 是一样的!

【发现源码】这里更加直接,搜索 epoll_create 肯定就能找到

问题的关键

此时问题的关键基本就能了解了,每个 worker 都有处理能力,请求来了此时应该唤醒谁呢?讲道理那不是所有 epoll 都会有事件,所有 worker 都 accept 请求?显然这样是不行的。那么 nginx 是如何解决的呢?

相关视频推荐

Nginx源码解析惊群方案、惊群现象演示、锁方案讲解

16w行的nginx源码,如何才能读懂呢?全面分析nginx的机制

epoll的原理与使用,epoll比select/poll强在哪里?

Linux C/C++开发(后端/音视频/游戏/嵌入式/高性能网络/存储/基础架构/安全)

需要C/C++ Linux服务器架构师学习资料加qun812855908获取(资料包括C/C++,Linux,golang技术,Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,TCP/IP,协程,DPDK,ffmpeg等),免费分享

如何解决

解决方式一共有三种,下面我们一个个来看:

  1. accept_mutex(应用层的解决方案)

  2. EPOLLEXCLUSIVE(内核层的解决方案)

  3. SO_REUSEPORT(内核层的解决方案)

accept_mutex

看到 mutex 可能你就知道了,锁嘛!这也是对于高并发处理的 ”基操“ 遇事不决加锁,没错,加锁肯定能解决问题。https://github.com/nginx/nginx/blob/b489ba83e9be446923facfe1a2fe392be3095d1f/src/event/ngx_event_accept.c#L328

具体代码就不展示了,其中细节很多,但本质很容易理解,就是当请求来了,谁拿到了这个锁,谁就去处理。没拿到的就不管了。锁的问题很直接,除了慢没啥不好的,但至少很公平。

EPOLLEXCLUSIVE

EPOLLEXCLUSIVE 是 2016 年 4.5+ 内核新添加的一个 epoll 的标识。它降低了多个进程/线程通过 epoll_ctl 添加共享 fd 引发的惊群概率,使得一个事件发生时,只唤醒一个正在 epoll_wait 阻塞等待唤醒的进程(而不是全部唤醒)。

关键是:每次内核只唤醒一个睡眠的进程处理资源

但,这个方案不是完美的解决了,它仅是降低了概率哦。为什么这样说呢?相比于原来全部唤醒,那肯定是好了不少,降低了冲突。但由于本质来说 socket 是共享的,当前进程处理完成的时间不确定,在后面被唤醒的进程可能会发现当前的 socket 已经被之前唤醒的进程处理掉了。

SO_REUSEPORT

Nginx 在 1.9.1 版本加入了这个功能 https://www.nginx.com/blog/socket-sharding-nginx-release-1-9-1/

其本质是利用了 Linux 的 reuseport 的特性,使用 reuseport 内核允许多个进程 listening socket 到同一个端口上,而从内核层面做了负载均衡,每次唤醒其中一个进程。

反应到 Nginx 上就是,每个 Worker 进程都创建独立的 listening socket,监听相同的端口,accept 时只有一个进程会获得连接。效果就和下图所示一样。

而使用方式则是:

http {server {listen 80 reuseport;server_name  localhost;# ...}
}

从官方的测试情况来看确实是厉害

当然,正所谓:完事无绝对,技术无银弹。这个方案的问题在于内核是不知道你忙还是不忙的。只会无脑的丢给你。与之前的抢锁对比,抢锁的进程一定是不忙的,现在手上的工作都已经忙不过来了,没机会去抢锁了;而这个方案可能导致,如果当前进程忙不过来了,还是会只要根据 reuseport 的负载规则轮到你了就会发送给你,所以会导致有的请求被前面慢的请求卡住了。

总结

本文,从了解什么 ”惊群效应“ 到 nginx 架构和 epoll 处理的原理,最终分析三种不同的处理 “惊群效应” 的方案。分析到这里,我想你应该明白其实 nginx 这个多队列服务模型是所存在的一些问题,只不过绝大多数场景已经完完全全够用了。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

开发vue3 UI组件库,并且发布到NPM

目录 1.创建vue3工程 2.创建package文件 3.编写组件&#xff0c;并且导出 4.编写package.json 5.npm账号注册登录并发布 6.从npm安装使用 7.注意事项 1.创建vue3工程 &#xff08;1&#xff09;初始化Vue项目 cnpm create vite &#xff08;2&#xff09;进入文件夹…

【算法练习Day48】回文子串最长回文子序列

​&#x1f4dd;个人主页&#xff1a;Sherry的成长之路 &#x1f3e0;学习社区&#xff1a;Sherry的成长之路&#xff08;个人社区&#xff09; &#x1f4d6;专栏链接&#xff1a;练题 &#x1f3af;长路漫漫浩浩&#xff0c;万事皆有期待 文章目录 回文子串最长回文子序列总结…

K8S 集群搭建

1、搭建清单 2台linux服务器&#xff08;一个master节点&#xff0c;一个node节点&#xff09;&#xff0c;建议搭3台&#xff08;一个master&#xff0c;两个node&#xff09; 我使用的是腾讯云&#xff0c;节点与节点使用公网IP通信 确保2台服务器都安装了docker 2、服务…

公立医院综合绩效核算系统全套源码,灵活的绩效考评体系配置方案,支持不同科室、不同人员的方案考评

医院综合绩效核算系统源码 医院绩效考核系统以医院的发展战略为导向&#xff0c;把科室、员工的绩效考核跟战略发展目标紧密结合&#xff0c;引导医院各个科室、各员工的工作目标跟医院的发展目标结合在一起&#xff0c;实现医院的优化发展。系统提供灵活的绩效考评体系配置方…

Java封装一个根据指定的字段来获取子集的工具类

工具类 ZhLambdaUtils SuppressWarnings("all") public class ZhLambdaUtils {/*** METHOD_NAME*/private static final String METHOD_NAME "writeReplace";/*** 获取到lambda参数的方法名称** param <T> parameter* param function functi…

SoftwareTest6 - 用 Selenium 怎么点点点

用 Selenium 来点点点 一 . 什么是自动化 ?1.1 自动化测试的分类接口自动化测试UI 自动化测试 (界面测试) 1.2 实现自动化测试的工具 : selenium环境部署驱动 二 . selenium 的使用2.1 一个简单的示例 : 让谷歌浏览器在百度首页搜索蔡徐坤准备工作编写代码 2.2 打开谷歌浏览器…

如何将微软 Office 宏转换为 ONLYOFFICE 宏

想要将微软 Office VBA 宏转换为可在 ONLYOFFICE 中无缝使用的宏&#xff1f;嗯&#xff0c;虽然这种需求并没有直接的解决方案&#xff0c;不过我们也会在本文中介绍 VBA 宏的转换步骤——正好我们手上也有一个来自用户的实际案例可供参考。 VBA 宏 以下是原始的 VBA 宏代码&…

桥接模式(结构型)

目录 一、前言 二、桥接模式 三、总结 一、前言 桥接模式&#xff08;Bridge Pattern&#xff09;是一种常用的设计模式&#xff0c;它可以将抽象部分与它的实现部分分离&#xff0c;使它们可以独立地变化。桥接模式通常用于需要在多个维度上扩展一个类的情况&#xff0c;或…

OpenMMlab导出yolov3模型并用onnxruntime和tensorrt推理

导出onnx文件 直接使用脚本 import torch from mmdet.apis import init_detector, inference_detectorconfig_file ./configs/yolo/yolov3_mobilenetv2_8xb24-ms-416-300e_coco.py checkpoint_file yolov3_mobilenetv2_mstrain-416_300e_coco_20210718_010823-f68a07b3.pth…

一个破单机,也要用远程缓存?

大家好&#xff0c;豆小匠终于开始Coding了&#xff0c;这期来聊聊实战相关的杂谈。 正文开始&#xff01; 作为编程萌新的时候&#xff0c;总想着把程序做复杂&#xff0c;堆技术栈。 但是程序是为场景服务的&#xff0c;比如&#xff0c;我想提高接口的响应速度&#xff0c…

C/C++计算乘积 2021年9月电子学会青少年软件编程(C/C++)等级考试一级真题答案解析

目录 C/C计算乘积 一、题目要求 1、编程实现 2、输入输出 二、算法分析 三、程序编写 四、程序说明 五、运行结果 六、考点分析 C/C计算乘积 2021年9月 C/C编程等级考试一级编程题 一、题目要求 1、编程实现 给定两个数a,b&#xff0c;计算它们的乘积 2、输入输出…

asp.net实验管理系统VS开发sqlserver数据库web结构c#编程web网页设计

一、源码特点 asp.net 实验管理系统 是一套完善的web设计管理系统&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为vs2010&#xff0c;数据库为sqlserver2008&#xff0c;使用c#语言开发。 asp.net实验管理系统1 应用技术&am…

高质量实时渲染笔记

文章目录 Real-time shadows1 自遮挡问题2 解决阴影detach问题&#xff1f;3 Aliasing4 近似积分5 percentage closer soft shadows(PCSS)percenta closer filtering(PCF)PCSS的思想 6 Variance Soft Shadow Mapping (VSSM)步骤Moment Shadow Mapping 7 Distance field shadow …

macOS 13.6 及后续系统安装 Asahi Linux 将破坏引导

导读Asahi Linux 是一个致力于为 Apple Silicon 设备带来 Linux 支持的项目&#xff0c;日前有用户反馈称&#xff0c;若在相关设备上安装了 macOS 13.6-14&#xff0c;再安装 Asahi Linux &#xff0c;就会导致系统引导失败&#xff0c;出现“黑屏”情况。 目前 Asahi Linux 项…

Docker - 网络

Docker - 网络 理解Docker0 # 我们发现这个容器带来网卡&#xff0c;都是一对对的 # evth-pair 就是一对的虚拟设备接口&#xff0c;他们都是成对出现的&#xff0c;一段连着协议&#xff0c;一段彼此相连 # 正因为有了这个特性&#xff0c;evth-pair 充当一个桥梁&#xff0…

智慧隧道:TSINGSEE青犀远程视频AI智能监管平台保障隧道施工安全

一、背景与需求分析 随着我国交通运输量的增加以及新基建的不断规划和建设&#xff0c;公路建设工作也在持续开展中。高速公路隧道属于特殊构造段&#xff0c;因为隧道空间小&#xff0c;密闭性强&#xff0c;施工过程中一旦发生火灾、事故等&#xff0c;将带来重大人员伤亡和…

软件工程-第7章 面向对象方法基础

第7章 面向对象方法基础 面向对象的基本概念 面向对象方法的世界观&#xff1a;一切系统都是由对象构成的&#xff0c;他们的相互作用、相互影响&#xff0c;构成了大千世界的各式各样系统。面向对象方法是一种以对象、对象关系等来构造软件系统模型的系统化方法。 面向对象 …

vim批量多行缩进调整

网上其他教程&#xff1a; ctrl v 或者 v进行visual模式按方向键<&#xff0c;>调整光标位置选中缩进的行Shift > &#xff08;或者 Shift < &#xff09;进行左右缩进。 我只想说&#xff0c;乱七八糟&#xff0c;根本不管用 本文教程&#xff1a; 增加缩进…

U-Mail海外邮件中继帮您解决企业邮件退信难题

过去一年&#xff0c;国内外形势严峻复杂&#xff0c;但中国外贸顶住压力、爬坡过坎&#xff0c;进出口规模冲破40万亿元大关&#xff0c;高达42万亿元人民币&#xff0c;中国连续6年位居货物贸易第一大国。随着我国疫情防控措进入新阶段&#xff0c;“拼经济”正在成为各地的一…

XUbuntu22.04之安装pkg-config(一百九十二)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 人生格言&#xff1a; 人生…