当前位置: 首页 > news >正文

Nginx实现高并发

          注:文章是4年前在自己网站上写的,迁移过来了。现在看我之前写的这篇文章,描述得不是特别详细,但描述了Nginx的整体架构思想。如果对Nginx玩得透得或者想了解深入的,可以在网上找找其他的文章。

...................................................................分割线...........................................................................

        Nginx实现高并发的模型是多进程+IO多路复用的方式,实现了系统的异步非阻塞IO。

        其实乍看到这是有些疑惑的。使用的epoll这种IO多路复用方式,OS层本身是同步非阻塞的,那为什么说实现了异步呢。这就跟Nginx的实现机制有关系了。关于IO多路复用可见: 并发编程之I/O多路复用

        Nginx的多进程模型是一个master+多个worker。master的作用主要是创建,管理子进程worker。之前写过一篇关于gunicorn介绍的,其进程模型也是采用了相同的思想,只是每个worker的处理方式不同。具体可见: Gunicorn介绍

        当启动Nginx时,master进程建立了socket文件描述符,然后pre-fork出子进程,子进程会继承master的socket,并执行accept开始listen。

        刚才说了,master不负责处理客户端的request请求。真正处理请求的是worker。当有request到来时,会有一个worker进程采用IO多路复用的机制进行处理。

master的主要作用:

  • 接收来自外界的信号; 比如我们在kill进程时,可以直接kill主进程。
  • 向各个worker进程发送信号;
  • 监控worker进程状态;
  • 当worker退出后(异常情况下),自动重新启动新的worker进程

来一张网络上请求处理的示意图:

        那么现在问题来了,因为同时有多个woker都在监听,那如何保证同时只有一个worker处理,不会同时唤起所有worker,引起惊群效应呢?

        nginx引入了一个叫accept_mutex的互斥锁,同一时刻可以保证只有一个worker获取到互斥锁,只有成功获得锁的worker才可以accept请求,执行后续的请求处理流程,同时ngx_accept_disabled减1。accept处理完之后会释放锁。如果某个worker的队列中连接数已经超过了最大连接的7/8就不再accept请求。

        关于nginx的accep_mutax具体可参考: accept_mutex与性能的关系 (nginx)

        不过对于只有几个worker的时候,互斥锁没必要打开,就算是多个worker去竞争所带来的消耗也没有多大。此外,对于长连接,可能会导致某个worker长时间占用锁,拖垮整个nginx的性能。

        其实后来nginx还引入了两种方式:EPOLLEXCLUSIVE和SO_REUSEPORT,不过这个还要依赖于操作系统的支持。SO_REUSEPORT这个应该在Netty中应该都见过,它会允许多个进程绑定到同一个socket上,相互独立。内核会自动实现多个进程的负载均衡。具体可参考: 惊群和OP_REUSEPORT

        Nginx是基于事件驱动的,一个请求过程可以根据事件的触发方式划分为多个阶段,每个阶段都可以由事件收集、分发器来触发。

        比如一个请求的读阶段被一个读消费者处理之后,然后就进入空闲状态去处理其他请求片段。等下一次事件出现时,事件分发器会调用事件消费者去处理。这里需要注意的是虽然一个请求分了很多阶段,但他们都是在同一个worker内的。

        可以看到,通过这种方式,Nginx的IO多路复用不出现空闲事件,间接上实现了异步非阻塞,是框架层面实现的异步,而非OS层面epoll的同步。

 下面代码展示了Nginx主要处理请求的大致过程:

for( ; ; )  //  无限循环
{nfds = epoll_wait(epfd,events,20,500);  //  最长阻塞 500sfor(i=0;i<nfds;++i){if(events[i].data.fd==listenfd) //有新的连接{connfd = accept(listenfd,(sockaddr *)&clientaddr, &clilen); //accept这个连接ev.data.fd=connfd;ev.events=EPOLLIN|EPOLLET;epoll_ctl(epfd,EPOLL_CTL_ADD,connfd,&ev); //将新的fd添加到epoll的监听队列中}else if( events[i].events&EPOLLIN ) //接收到数据,读socket{n = read(sockfd, line, MAXLINE)) < 0    //读ev.data.ptr = md;     //md为自定义类型,添加数据ev.events=EPOLLOUT|EPOLLET;epoll_ctl(epfd,EPOLL_CTL_MOD,sockfd,&ev);//修改标识符,等待下一个循环时发送数据,异步处理的精髓}else if(events[i].events&EPOLLOUT) //有数据待发送,写socket{struct myepoll_data* md = (myepoll_data*)events[i].data.ptr;    //取数据sockfd = md->fd;send( sockfd, md->ptr, strlen((char*)md->ptr), 0 );        //发送数据ev.data.fd=sockfd;ev.events=EPOLLIN|EPOLLET;epoll_ctl(epfd,EPOLL_CTL_MOD,sockfd,&ev); //修改标识符,等待下一个循环时接收数据}else{//其他的处理}}
}

相关文章:

Nginx实现高并发

注&#xff1a;文章是4年前在自己网站上写的&#xff0c;迁移过来了。现在看我之前写的这篇文章&#xff0c;描述得不是特别详细&#xff0c;但描述了Nginx的整体架构思想。如果对Nginx玩得透得或者想了解深入的&#xff0c;可以在网上找找其他的文章。 ......................…...

华为荣耀终端机试真题

文章目录 一 、字符展开(200分)1.1 题目描述1.2 解题思路1.3 解题代码二、共轭转置处理(100分)2.1 题目描述2.3 源码内容一 、字符展开(200分) 1.1 题目描述 // 64 位输出请用 printf(“%lld”)给定一个字符串,字符串包含数字、大小写字母以及括号(包括大括号、中括号…...

C++ Qt开发:QNetworkInterface网络接口组件

Qt 是一个跨平台C图形界面开发库&#xff0c;利用Qt可以快速开发跨平台窗体应用程序&#xff0c;在Qt中我们可以通过拖拽的方式将不同组件放到指定的位置&#xff0c;实现图形化开发极大的方便了开发效率&#xff0c;本章将重点介绍如何运用QNetworkInterface组件实现查询详细的…...

Luajit 2023移动版本编译 v2.1.ROLLING

文章顶部有编好的 2.1.ROLLING 2023/08/21版本源码 Android 64 和 iOS 64 luajit 目前最新的源码tag版本为 v2.1.ROLLING on Aug 21, 2023应该是修正了很多bug, 我是出现下面问题才编的. cocos2dx-lua 游戏 黑屏 并报错: [LUA ERROR] bad light userdata pointer 编…...

c++ 常用新特性总结【c++11】,【c++14】,【c++17】,【c++20】

文章目录 常用的c11新特性1.自动推导类型(auto)2.lambda表达式3.智能指针4.范围for循环5.右值引用 - 移动语义6.类型别名7.constexpr8.static_assert(静态断言)9.nullptr10.列表初始化11.继承构造函数12.显示虚函数重载(override)13.final14.变长模板参数15.新的容器与算法16.强…...

Feign实现微服务间远程调用续;基于Redis实现消息队列用于延迟任务的处理,Redis分布式锁的实现;(黑马头条Day05)

目录 延迟任务和定时任务 使用Redis设计延迟队列原理 点评项目中选用list和zset两种数据结构进行实现 如何缓解Redis内存的压力同时保证Redis中任务能够被正确消费不丢失 系统流程设计 使用Feign实现微服务间的任务消费以及文章自动审核 系统微服务功能介绍 提交文章-&g…...

CSS 常见属性设置

一. 文本属性 1.1. 装饰线 text-decoration text-decoration有如下常见取值: none&#xff1a;无任何装饰线&#xff08;可以去除a元素默认的下划线&#xff09;underline&#xff1a;下划线overline&#xff1a;上划线line-through&#xff1a;中划线&#xff08;删除线&…...

docker学习入门

1、docker简介 docker官网&#xff1a; www.docker.com dockerhub官网&#xff1a; hub.docker.com docker文档官网&#xff1a;docs.docker.com Docker是基于Go语言实现的云开源项目。 Docker的主要目标是&#xff1a;Build, Ship and Run Any App, Anywhere(构建&…...

蓝牙系列七:开源蓝牙协议栈BTStack数据处理

继续蓝牙系列的研究。 在上篇博客,通过阅读BTStack的源码,大体了解了其框架,对于任何一个BTStack的应用程序都有一个main函数,这个main函数是统一的。这个main函数做了某些初始化之后,最终会调用到应用程序提供的btstack_main,在btstack_main里面首先做一些初始化,然后…...

数据仓库作业一:第1章 绪论

目录 一、给出下列英文短语或缩写的中文名称&#xff0c;并简述其含义。二、简述操作型数据与分析型数据的主要区别。三、简述数据仓库的定义。四、简述数据仓库的特征。五、简述主题的定义。六、简述元数据的概念。七、简述数据挖掘的主要任务。八、简述数据挖掘的主要步骤。九…...

spring aop中获取request和response

Spring AOP 操作中如何使用request和response 实际使用时&#xff0c;如果方法一不行&#xff0c;请使用方法二 方法一 HttpServletRequest request ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); HttpServletResponse respons…...

在Mac上安装nginx+rtmp 本地服务器

需要使用终端命令&#xff0c;如果没有Homebrew&#xff0c;要安装Homebrew,执行&#xff1a; ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" 一、安装Nginx 1、先clone Nginx项目到本地&#xff1a; brew tap de…...

解决ChatGPT发送消息没有反应

ChatGPT发消息没反应 今天照常使用ChatGPT来帮忙码代码&#xff0c;结果发现发出去的消息完全没有反应&#xff0c;即不给我处理&#xff0c;也没有抱任何的错误&#xff0c;按浏览器刷新&#xff0c;看起来很正常&#xff0c;可以查看历史对话&#xff0c;但是再次尝试还是一…...

windows关闭copilot预览版

如果用户不想在windows系统当中启用Copilot&#xff0c;可以通过以下三种方式禁用。 第一种&#xff1a;隐藏Copilot 按钮 右键点击任务栏&#xff0c;取消勾选“显示 Copilot&#xff08;预览版&#xff09;按钮”&#xff0c;任务栏则不再显示&#xff0c;用户可以通过快捷键…...

基于Java的社区买菜系统(Vue.js+SpringBoot)

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、系统设计2.1 功能模块设计2.1.1 数据中心模块2.1.2 菜品分类模块2.1.3 菜品档案模块2.1.4 菜品订单模块2.1.5 菜品收藏模块2.1.6 收货地址模块 2.2 可行性分析2.3 用例分析2.4 实体类设计2.4.1 菜品分类模块2.4.2 菜品档案模块2.4.3…...

html--心花怒放

代码 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><title>Canvas 绘制一个❤</title><link rel"shortcut icon" href"../../assets/images/icon/favicon.ico" type"ima…...

FPGA的配置状态字寄存器Status Register

目录 简介 状态字定义 Unknown Device/Many Unknow Devices 解决办法 一般原因 简介 Xilinx的FPGA有多种配置接口&#xff0c;如SPI&#xff0c;BPI&#xff0c;SeletMAP&#xff0c;Serial&#xff0c;JTAG等&#xff1b;如果从时钟发送者的角度分&#xff0c;还可以…...

【HarmonyOS Arkts笔记】http网络请求封装

common.ts export default class CommonConstant {/*** The host address of the server.*/static readonly SERVER: string 请求接口地址;/*** The request success code.*/static readonly SUCCESS_CODE: number 200;/*** Read timeout.*/static readonly READ_TIMEOUT: n…...

html前端的几种加密/解密方式

HTML前端的加密解密方式有以下几种&#xff1a; 一、base64加密 Base64编码&#xff1a;Base64是一种将二进制数据转换为可打印字符的编码方式。在前端&#xff0c;可以使用JavaScript的btoa()函数进行Base64编码&#xff0c;使用atob()函数进行解码。 var str "hello…...

算法学习01:排序二分

算法学习01&#xff1a;排序&&二分 文章目录 算法学习01&#xff1a;排序&&二分前言需要记忆的模版&#xff1a;快速排序归并排序&#xff1a;整数二分&#xff1a;浮点数二分 一、排序1.快速排序2.归并排序&#xff1a; 二、二分1.整数2.浮点数 总结 前言 需要…...

基于Vue 3.0与Element Plus的Cron表达式可视化生成器技术架构解析

基于Vue 3.0与Element Plus的Cron表达式可视化生成器技术架构解析 【免费下载链接】no-vue3-cron 这是一个 cron 表达式生成插件,基于 vue3.0 与 element-plus 实现 项目地址: https://gitcode.com/gh_mirrors/no/no-vue3-cron no-vue3-cron作为一款基于现代前端技术栈的…...

五大专业模糊算法:obs-composite-blur让直播画面质感全面提升

五大专业模糊算法&#xff1a;obs-composite-blur让直播画面质感全面提升 【免费下载链接】obs-composite-blur A comprehensive blur plugin for OBS that provides several different blur algorithms, and proper compositing. 项目地址: https://gitcode.com/gh_mirrors/…...

告别移植恐惧:用LVGL官方Porting模板快速适配你的STM32屏幕(以NT35510/GT9147为例)

告别移植恐惧&#xff1a;用LVGL官方Porting模板快速适配你的STM32屏幕 第一次接触LVGL时&#xff0c;面对庞大的源码库和复杂的移植文档&#xff0c;相信不少开发者都会感到无从下手。作为一个从零开始踩过无数坑的嵌入式开发者&#xff0c;我想分享一个被大多数人忽略的高效方…...

2025届毕业生推荐的六大降AI率工具推荐

Ai论文网站排名&#xff08;开题报告、文献综述、降aigc率、降重综合对比&#xff09; TOP1. 千笔AI TOP2. aipasspaper TOP3. 清北论文 TOP4. 豆包 TOP5. kimi TOP6. deepseek 在学术写作跟内容创作这个领域当中&#xff0c;文字重复率过于高是较为常见的问题。专业降重…...

别再死记硬背GCN/GAT公式了!用PyTorch Geometric手写一个MPNN,彻底搞懂消息传递

从零实现MPNN&#xff1a;用PyTorch Geometric拆解图神经网络的消息传递本质 当你第一次接触图神经网络&#xff08;GNN&#xff09;时&#xff0c;是否曾被各种公式和概念搞得晕头转向&#xff1f;GCN的拉普拉斯矩阵、GAT的注意力系数...这些看似复杂的数学背后&#xff0c;其…...

毕业论文 | 基于光流的十字路口闯红灯车辆与行人检测识别系统【附完整matlab代码】

文章目录 摘要 Abstract 第1章 绪论 1.1 研究背景与意义 1.2 国内外研究现状 1.2.1 智能交通监控系统研究现状 1.2.2 光流法在交通检测中的应用现状 1.2.3 闯红灯检测技术研究现状 1.3 论文主要研究内容 1.4 论文结构安排 第2章 光流法理论基础 2.1 光流的基本概念 2.2 光流约束…...

AT32F403A/STM32F103内部Flash读写避坑指南:从扇区擦除到数据校验的实战经验

AT32F403A/STM32F103内部Flash读写避坑指南&#xff1a;从扇区擦除到数据校验的实战经验 在嵌入式开发中&#xff0c;内部Flash的可靠读写往往是产品稳定性的关键所在。许多开发者按照基础教程完成功能后&#xff0c;却在量产阶段遭遇数据丢失、写入失败等棘手问题。本文将深入…...

避开Conda环境冲突!在Ubuntu 20.04上丝滑安装ROS Noetic的保姆级教程

避开Conda环境冲突&#xff01;在Ubuntu 20.04上丝滑安装ROS Noetic的保姆级教程 当Python数据科学遇上机器人开发&#xff0c;Conda与ROS的环境变量冲突就像两个武林高手在狭窄的走廊里过招——稍有不慎就会两败俱伤。作为同时深耕AI和机器人领域的开发者&#xff0c;我经历过…...

如何快速解决Windows热键冲突问题:Hotkey Detective完全实战指南

如何快速解决Windows热键冲突问题&#xff1a;Hotkey Detective完全实战指南 【免费下载链接】hotkey-detective A small program for investigating stolen key combinations under Windows 7 and later. 项目地址: https://gitcode.com/gh_mirrors/ho/hotkey-detective …...

手把手教你部署Stable Diffusion 3.5 FP8:小白友好的AI绘画工具

手把手教你部署Stable Diffusion 3.5 FP8&#xff1a;小白友好的AI绘画工具 1. 前言&#xff1a;为什么选择SD 3.5 FP8&#xff1f; 如果你对AI绘画感兴趣&#xff0c;一定听说过Stable Diffusion这个强大的文本生成图像工具。今天我要介绍的是它的最新升级版本——Stable Di…...