Nginx — Nginx处理Web请求机制解析

一、Nginx请求默认页面资源

1、配置文件详解

 

 修改端口号为8080并重启服务:

二、Nginx进程模型

1、nginx常用命令解析

master进程:主进程(只有一个)

worker进程:工作进程(可以有多个,默认只有一个进程)

生命周期的原理:

信号: (操作人在执行以下指令操作的时候,master会转递给worker相关的信息让worker去进行相关的操作)

./nginx                  #开启nginx服务。
./nginx -s stop          #暴力的关闭,如果后端有用户在连接如果用此命令会导致连接全部中断,如果发现有恶意攻击和黑客入侵的情况下可以用此命令。
./nginx -s stop          #重新加载配置文件信息。
./nginx -s quit          #优雅的关闭,如果后端有用户在连接会等待连接完成之后再去关闭,同时不会让新的请求访问进来(只针对http请求如果不是http请求时不行的)。
./nginx -t               #检测配置文件的语法是否正确。
./nginx -v               #查看当前的配置信息。
./nginx -V               #显示详细信息,包括了nginx的版本、gcc版本、configure编译路径等。
./nginx -c               #代表手动切换nginx的配置文件。
./nginx -h & ./nginx -h  #显示nginx的帮助命令。

 

 

每个worker之间相对独立,如果某个worker收到黑客的攻击,那么运维人员只需要关闭相关的worker进程,如果某个worker进程不存在只需要master重新fork以下即可。

 2、修改worker的进程数

 

三、Worker抢占机制

当client发起了请求之后client和worker之间会有一个护事锁(accept_mutex)服务端的众多worker会去抢这个锁,哪个worker抢到就由哪个worker来进行处理。

 

 

四、传统服务事件处理

假设一个client在进行请求的时候由worker1来进行处理,在处理的过程中用时比较长而且卡住了,客户端的请求就会被阻塞,假设在阻塞的过程中又有新的请求进来(假设client2、client3也同时连接到worker)要去处理。只有阻塞的请求处理完毕才回去处理client2、client3,所以master会去fork一个新worker进程。(在告并发情况下,这样的消耗会很大而且占用的资源会比较多)。

 

 

五、Nginx时间处理

假设一个client在进行请求的时候由worker1来进行处理,在处理的过程中用时比较长而且卡住了。对于Nginx而言是异步非阻塞的,如果发生阻塞同时又有新的请求进来那么worker会去处理下一个请求。用到的模型为epoll,(如果用到epoll那么一个worker进程可以处理6~8w的请求量,并且不会产生很多的开销),那么需要越高的并发量只需要增加服务器的配置就可以了(有钱解决)。

(一)Nginx的events模块支持的多种事件模型支持的模型

Nginx 的 events 模块主要用于配置 Nginx 如何处理连接,它提供了多种事件模型,以适应不同的操作系统和应用场景。下面为你详细介绍 Nginx 支持的主要事件模型:

1. select 模型

  • 原理select 是一种较为传统的事件驱动模型,它通过对文件描述符集合进行轮询,检查是否有文件描述符处于可读、可写或异常状态。当有事件发生时,select 函数会返回发生事件的文件描述符数量,然后程序需要遍历文件描述符集合来确定具体是哪些文件描述符发生了事件。
  • 适用场景:适用于连接数较少的场景,因为 select 模型在处理大量连接时,轮询操作会带来较高的 CPU 开销,性能会显著下降。同时,select 模型对文件描述符数量有限制,通常最大为 1024。
  • 配置示例
 

nginx

events {use select;worker_connections 1024;
}

2. poll 模型

  • 原理poll 是对 select 模型的改进,它同样采用轮询的方式检查文件描述符的状态,但 poll 没有文件描述符数量的限制。poll 使用一个结构体数组来存储文件描述符和对应的事件,避免了 select 对文件描述符数量的硬限制。
  • 适用场景:适用于连接数相对较多,但仍然不是非常大的场景。相比于 selectpoll 在处理大量连接时性能有所提升,但在处理超大量连接时,轮询操作仍然会带来较高的 CPU 开销。
  • 配置示例
 

nginx

events {use poll;worker_connections 2048;
}

3. epoll 模型

  • 原理epoll 是 Linux 内核为处理大批量文件描述符而作了改进的 poll,是 Linux 下多路复用 IO 接口 select/poll 的增强版本。它采用事件驱动的方式,只关注那些有事件发生的文件描述符,避免了对所有文件描述符的轮询,从而提高了效率。epoll 使用内核和用户空间共享内存的方式,减少了数据的拷贝次数。
  • 适用场景:适用于 Linux 系统下处理大量并发连接的场景,是 Nginx 在 Linux 系统上的首选事件模型。
  • 配置示例
 

nginx

events {use epoll;worker_connections 65535;
}

4. kqueue 模型

  • 原理kqueue 是 FreeBSD 系统上的一种高效事件通知机制,类似于 Linux 下的 epoll。它采用事件队列的方式,当有事件发生时,会将事件添加到队列中,程序可以从队列中获取发生事件的文件描述符。
  • 适用场景:适用于 FreeBSD 系统,在处理大量并发连接时性能较好。
  • 配置示例
 

nginx

events {use kqueue;worker_connections 65535;
}

5. rtsig 模型

  • 原理rtsig 是基于实时信号实现的事件模型,它通过发送实时信号来通知程序有事件发生。
  • 适用场景:该模型在实际应用中使用较少,因为实时信号的处理有一些限制,并且性能不如 epoll 和 kqueue 等模型。
  • 配置示例
 

nginx

events {use rtsig;worker_connections 1024;
}

6. /dev/poll 模型

  • 原理/dev/poll 是 Solaris 系统上的一种事件通知机制,它通过读取 /dev/poll 设备文件来获取事件信息。
  • 适用场景:适用于 Solaris 系统,在该系统上可以提供较好的性能。
  • 配置示例
 

nginx

events {use /dev/poll;worker_connections 65535;
}

自动选择模型

如果不指定 use 指令,Nginx 会根据操作系统自动选择最合适的事件模型。例如,在 Linux 系统上会优先选择 epoll 模型,在 FreeBSD 系统上会优先选择 kqueue 模型。示例如下:

 

nginx

events {worker_connections 65535;
}
 

在实际应用中,建议根据服务器的操作系统和具体的业务场景选择合适的事件模型,以提高 Nginx 的性能和稳定性。

(二)nginx默认的模型是epoll 

epoll 是 Linux 内核为处理大批量文件描述符而作了改进的 poll,是 Linux 下多路复用 IO 接口 select/poll 的增强版本,它能显著提高程序在大量并发连接中只有少量活跃的情况下的系统 CPU 利用率。下面从几个方面详细介绍 epoll 模型:

基本概念

在网络编程中,服务器需要处理多个客户端的连接请求,传统的方法(如 select 和 poll)在处理大量连接时性能会下降。epoll 则通过事件驱动的方式,只关注那些有事件发生的文件描述符,避免了对所有文件描述符的轮询,从而提高了效率。

工作原理

epoll 的工作流程主要分为三个步骤:

 
  1. 创建 epoll 实例:使用 epoll_create 或 epoll_create1 函数创建一个 epoll 实例,它会返回一个文件描述符,后续的操作都基于这个描述符进行。
  2. 注册事件:使用 epoll_ctl 函数向 epoll 实例中添加、修改或删除需要监控的文件描述符以及对应的事件。例如,可以监控文件描述符的可读、可写等事件。
  3. 等待事件发生:使用 epoll_wait 函数等待事件的发生。当有事件发生时,该函数会返回有事件发生的文件描述符列表,程序可以对这些文件描述符进行相应的处理。

代码示例

以下是一个简单的使用 epoll 实现的 TCP 服务器示例代码:

 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <sys/epoll.h>
#include <unistd.h>#define MAX_EVENTS 10
#define BUF_SIZE 1024int main() {int listen_fd, epoll_fd;struct sockaddr_in server_addr;struct epoll_event ev, events[MAX_EVENTS];// 创建监听套接字listen_fd = socket(AF_INET, SOCK_STREAM, 0);if (listen_fd == -1) {perror("socket");return 1;}// 初始化服务器地址memset(&server_addr, 0, sizeof(server_addr));server_addr.sin_family = AF_INET;server_addr.sin_addr.s_addr = INADDR_ANY;server_addr.sin_port = htons(8080);// 绑定地址if (bind(listen_fd, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1) {perror("bind");close(listen_fd);return 1;}// 监听连接if (listen(listen_fd, SOMAXCONN) == -1) {perror("listen");close(listen_fd);return 1;}// 创建 epoll 实例epoll_fd = epoll_create1(0);if (epoll_fd == -1) {perror("epoll_create1");close(listen_fd);return 1;}// 将监听套接字添加到 epoll 实例中ev.events = EPOLLIN;ev.data.fd = listen_fd;if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, listen_fd, &ev) == -1) {perror("epoll_ctl: listen_fd");close(listen_fd);close(epoll_fd);return 1;}while (1) {int nfds = epoll_wait(epoll_fd, events, MAX_EVENTS, -1);if (nfds == -1) {perror("epoll_wait");continue;}for (int i = 0; i < nfds; i++) {if (events[i].data.fd == listen_fd) {// 处理新的连接struct sockaddr_in client_addr;socklen_t client_addr_len = sizeof(client_addr);int conn_fd = accept(listen_fd, (struct sockaddr *)&client_addr, &client_addr_len);if (conn_fd == -1) {perror("accept");continue;}// 将新的连接添加到 epoll 实例中ev.events = EPOLLIN;ev.data.fd = conn_fd;if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, conn_fd, &ev) == -1) {perror("epoll_ctl: conn_fd");close(conn_fd);}} else {// 处理客户端数据char buf[BUF_SIZE];ssize_t n = read(events[i].data.fd, buf, BUF_SIZE);if (n <= 0) {// 客户端关闭连接close(events[i].data.fd);epoll_ctl(epoll_fd, EPOLL_CTL_DEL, events[i].data.fd, NULL);} else {// 回显数据给客户端write(events[i].data.fd, buf, n);}}}}// 关闭监听套接字和 epoll 实例close(listen_fd);close(epoll_fd);return 0;
}

优点

  • 高效处理大量连接epoll 使用事件驱动机制,只关注有事件发生的文件描述符,避免了 select 和 poll 对所有文件描述符的轮询,因此在处理大量并发连接时性能更优。
  • 内存拷贝优化epoll 使用内核和用户空间共享内存的方式,减少了数据的拷贝次数,提高了效率。
  • 水平触发和边缘触发模式epoll 支持水平触发(LT)和边缘触发(ET)两种模式,开发者可以根据具体需求选择合适的模式。

缺点

  • 平台依赖性epoll 是 Linux 特有的,在其他操作系统(如 Windows、macOS)上无法使用。
  • 实现复杂度较高:相比于 select 和 pollepoll 的使用和实现相对复杂,需要开发者对其原理有深入的理解。

 注:worker的进程要根据CPU实际情况来定不是越高越高,如果太高会造成请求访问卡顿。影响业务的正常运行。

epoll的配置

events {#默认使用epolluse epoll;#每个worker允许的客端最大连接数worker_connections  1024;
}

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

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

相关文章

【C++标准IO库】字符串流

目录 一、字符串流概述 1.1 流的概念回顾 1.2 字符串流的定义和作用 二、istringstream 的使用 2.1 基本用法 2.2 常见应用场景 三、ostringstream 的使用 3.1 基本用法 3.2 常见应用场景 四、stringstream 的使用 4.1 基本用法 4.2 常见应用场景 五、字符串流的错…

C语言pthread库的线程休眠和唤醒的案例

一、代码如下 #include<stdio.h> #include<pthread.h> // 定义独占锁 pthread_mutex_t mutex; // 定义条件信号对象 pthread_cond_t condition; // 初始化函数 void init(){ int code pthread_mutex_init(&mutex, NULL); printf("共享锁初…

人脸照片比对 API 接口如何对接?

随着数字化程度加深&#xff0c;身份验证的重要性也日益凸显&#xff0c;它成为保障个人信息安全、维护交易秩序的关键环节。人脸照片比对 API 接口作为连接人脸比对技术与各类应用的桥梁&#xff0c;正发挥着越来越重要的作用&#xff0c;成为众多企业和开发者实现高效、安全身…

java学习笔记9——常用类

字符串相关的类&#xff1a; String 指向同一个地址可才相等 注意这个地方&#xff0c;两个person对象的name实际上指向的是同一个字符串常量池&#xff08;Tom&#xff09; String常用方法 总结&#xff1a; 1.string类的理解(以JDK8为例说明) 1.1 类的声明 public final cl…

Day 09

文章目录 指针数组指针和函数技术名词解释技术细节课堂笔记 指针数组 #include<stdio.h> int main() {int a[3] {0,1,2};//指针数组&#xff0c;它是数组&#xff0c;每个元素都是指针int *p[3];p[0] &a[0];p[0] a;p[1] &a[1];p[1] a1;p[2] &a[2];p[…

Nginx — Nginx安装证书模块(配置HTTPS和TCPS)

一、安装和编译证书模块 [rootmaster nginx]# wget https://nginx.org/download/nginx-1.25.3.tar.gz [rootmaster nginx]# tar -zxvf nginx-1.25.3.tar.gz [rootmaster nginx]# cd nginx-1.25.3 [rootmaster nginx]# ./configure --prefix/usr/local/nginx --with-http_stub_…

计算机网络 用deepseek帮助整理的复习资料(一)

### 计算机网络基础知识整理 --- #### **一、网络类型** 1. **局域网 (LAN)** - **定义**&#xff1a;覆盖小范围&#xff08;如家庭、教室、公司&#xff09;。 - **特点**&#xff1a;高带宽、低延迟&#xff0c;设备通过交换机互联。 - **示例**&#xff1…

Linux SCP传输文件免密配置

文章目录 Linux SCP传输文件免密配置生成SSH密钥对将公钥复制到远程服务器测试SSH连接使用SCP免密传输文件可选配置带密码的秘钥连接处理使用 ssh-agent进行缓存管理&#xff08;该方式只能确保同一个回话中&#xff0c;多次传输只输一次密码&#xff09;使用 keychain&#xf…

数字电子技术基础(三十六)——利用Multisim软件实现3线-8线译码器

目录 1 手动方式实现3线-8线译码器 2 使用字选择器实现3线-8线译码器 现在尝试利用Multisim软件来实现3线-8线译码器。本实验目的是验证74LS138的基本功能&#xff0c;简单来说就是“N中选1”。 实验设计&#xff1a; &#xff08;1&#xff09;使能信号&#xff1a;时&am…

wait和notify : 避免线程饿死(以及votile内存可见性和指令重排序问题)

各位看官&#xff0c;大家早安午安晚安呀~~~ 如果您觉得这篇文章对您有帮助的话 欢迎您一键三连&#xff0c;小编尽全力做到更好 欢迎您分享给更多人哦 今天我们来学习&#xff1a;wait和notify : 避免线程饿死&#xff08;以及votile内存可见性和指令重排序问题&#xff09; …

HarmonyOS 介绍

HarmonyOS简介 随着万物互联时代的开启&#xff0c;应用的设备底座将从几十亿手机扩展到数百亿IoT设备。全新的全场景设备体验&#xff0c;正深入改变消费者的使用习惯。 同时应用开发者也面临设备底座从手机单设备到全场景多设备的转变&#xff0c;全场景多设备的全新底座&am…

【视觉提示学习】3.28阅读随想

2109.01134 CoOp通过可学习的向量来建模提示的上下文词汇&#xff0c;这些向量可以用随机值或预训练的词嵌入进行初始化&#xff08;见图2&#xff09;。我们提供了两种实现方式&#xff0c;以处理不同性质的任务&#xff1a;一种是基于统一上下文&#xff08;unified context…

计算机求职面试中高频出现的经典题目分类整理

以下为计算机求职面试中高频出现的经典题目分类整理&#xff0c;涵盖技术核心与深度考察方向&#xff0c;答案要点已附解析思路&#xff1a; 一、数据结构与算法 链表操作 题目&#xff1a;反转链表&#xff08;迭代/递归实现&#xff09;考察点&#xff1a;指针操作、递归思维…

uniapp选择文件使用formData格式提交数据

1. Vue实现 在vue项目中,我们有个文件,和一些其他字段数据需要提交的时候,我们都是使用axios 设置请求头中的Content-Type: multipart/form-data,然后new FormData的方式来进行提交。方式如下: const sendRequest = () => {const formData = new FormData()formData…

BeanDefinition和Beanfactory实现一个简单的bean容器

目录 什么是 Springbean 容器 设计思路 图解 参考文章 开源地址 BeanDefinition 类 BeanFactory 类 测试类 什么是 Springbean 容器 Spring 包含并管理应用对象的配置和生命周期&#xff0c;在这个意义上它是一种用于承载对象的容器&#xff0c;你可以配置你的每个 Bea…

AI Agent开发大全第十四课-零售智能导购智能体的RAG开发理论部分

开篇 经过前面的一些课程,我们手上已经积累了各种LLM的API调用、向量库的建立和使用、embedding算法的意义和基本使用。 这已经为我们具备了开发一个基本的问答类RAG的开发必需要素了。下面我们会来讲一个基本问答类场景的RAG,零售中的“智能导购”场景。 智能导购 大家先…

向字符串添加空格

给你一个下标从 0 开始的字符串 s &#xff0c;以及一个下标从 0 开始的整数数组 spaces 。 数组 spaces 描述原字符串中需要添加空格的下标。每个空格都应该插入到给定索引处的字符值 之前 。 例如&#xff0c;s "EnjoyYourCoffee" 且 spaces [5, 9] &#xff0…

百人会上的蔚小理与「来的刚刚好」的雷军

这就是2025百人会上的蔚小理&#xff0c;努力的李斌、宣扬飞行汽车的何小鹏与大讲开源的李想。那么小米汽车的模式是什么呢&#xff1f;站在蔚小理的肩上。 这就是2025百人会上的蔚小理&#xff0c;努力的李斌、宣扬飞行汽车的何小鹏与大讲开源的李想。那么小米汽车的模式是什么…

解锁Nginx路由器匹配规则

引言 Nginx 无疑是一款备受瞩目的明星产品。它以其高性能、高可靠性以及出色的并发处理能力&#xff0c;在众多 Web 服务器和反向代理服务器中脱颖而出 &#xff0c;广泛应用于各类网站和应用程序中。据统计&#xff0c;超过 30% 的网站都在使用 Nginx 作为其 Web 服务器&…

传统策略梯度方法的弊端与PPO的改进:稳定性与样本效率的提升

为什么传统策略梯度方法&#xff08;如REINFORCE算法&#xff09;在训练过程中存在不稳定性和样本效率低下的问题 1. 传统策略梯度方法的基本公式 传统策略梯度方法的目标是最大化累积奖励的期望值。具体来说&#xff0c;优化目标可以表示为&#xff1a; max ⁡ θ J ( θ )…