nginx如此之快【转载自公众号】
发布日期:2021-06-30 20:51:14
浏览次数:2
分类:技术文章
本文共 3607 字,大约阅读时间需要 12 分钟。
nginx的进程模型
nginx服务器 正常运行过程中01多进程:一个master进程 多个worker进程
02 master进程 :管理worker进程 03 对外接口:接收外部的操作(信号) 04 对内转发:根据外部的操作不同,通过信号管理worker 05 监控:监控worker进程的运行状态,worker进程异常终止后,自动启动worker进程 06 worker进程:所有worker进程都是平等的 07 实际处理:网络请求,由worker进程处理 08 worker进程数量:在nginx.conf中配置,一般设置为核心数,充分利用CPU资源,同时,避免进程数量过多,避免进程竞争CPU资源,增加上下文切换的损耗 思考: 01 请求是链接到nginx,master进程负责处理和转发? 02 如何选定那个worker进程处理请求?请求的处理结果,是否还要经过master进程? HTTP连接建立和请求处理过程 01 nginx启动时,master进程,加载配置文件 02 master进程,初始化监听的socket 03 master进程 fork出多个worker进程 04 worker进程,竞争新的连接,获胜者通过三次握手,建立socket连接,并处理请求nginx高性能、高并发
01 nginx采用:多进程+异步非阻塞方式(IO多路复用 epoll) 02 请求的完整过程: 03 建立连接请求 04 读取请求:解析请求 05 处理请求 06 响应请求 07 请求的完整过程,对应到底层就是读写socket事件。 nginx的事件处理模型 request:nginx中HTTP请求 基本的HTTP web server 工作模式: 01 接受请求:逐行读取请求行和请求头,判断有请求主体后,读取请求体。 02 处理请求 03 返回响应:根据处理结果,生成相应的HTTP请求(响应行、响应头、响应体) nginx也是这个套路,整体流程一致 模块化体系 nginx的模块根据其功能基本上可以分为以下几种类型:1.event module: 搭建了独立于操作系统的事件处理机制的框架,及提供了各具体事件的处理。包括ngx_events_module, ngx_event_core_module和ngx_epoll_module等。nginx具体使用何种事件处理模块,这依赖于具体的操作系统和编译选项。
2.phase handler: 此类型的模块也被直接称为handler模块。主要负责处理客户端请求并产生待响应内容,比如ngx_http_static_module模块,负责客户端的静态页面请求处理并将对应的磁盘文件准备为响应内容输出。 3.output filter: 也称为filter模块,主要是负责对输出的内容进行处理,可以对输出进行修改。例如,可以实现对输出的所有html页面增加预定义的footbar一类的工作,或者对输出的图片的URL进行替换之类的工作。 4.upstream: upstream模块实现反向代理的功能,将真正的请求转发到后端服务器上,并从后端服务器上读取响应,发回客户端。upstream模块是一种特殊的handler,只不过响应内容不是真正由自己产生的,而是从后端服务器上读取的。 5.load-balancer: 负载均衡模块,实现特定的算法,在众多的后端服务器中,选择一个服务器出来作为某个请求的转发服务器。 常见问题剖析 nginx vs apache 网络io模型: 01 nginx:io多路复用,epoll(FreeBSD上是kqueue) 02 高性能 03 高并发 04 占用系统资源少 05 Apache :阻塞+多进程/多线程 06 更稳定,bug少 07 模块更丰富场景;
处理多个请求时,可以采用:io多路复用或者阻塞io+多线程 io多路复用:一个线程 跟踪多个socket状态,哪个就绪;就读取哪个 阻塞io+多线程;每一个请求,新建一个服务线程 思考:io多路复用和多线程的使用场景? io多路复用:单个连接的请求处理速度没有优势,适合io密集型场景,事件驱动 大并发量:只使用一个线程,处理大量的并发请求,降低上下文环境切换损耗,也不需要考虑并发问题,相对可以处理更多的请求; 消耗更少的系统资源(不需要线程调度开销) 适用于长连接的情况(多线程模式长连接容易造成线程过多,造成频繁调度) 阻塞io+多线程:实现简单 可以依赖系统调度 适合CPU密集型场景 每个线程,都需要时间和空间 线程数量增长时,线程调度开销指数增长nginx最大连接数
基础背景:
01 nginx是多进程模型 worker进程用于处理请求 02 单个进程的链接数(文件描述fd)有上限(nofile):ulimit -n 03 nginx上配置单个worker进程的最大连接数 worker_connections 上限为 nofile 04 nginx上配置worker进程的数量:worker_precesses因此 nginx的最大连接数:
01 nginx的最大连接数:work进程数量*单个worker进程的最大连接数 02 上面是nginx作为通用服务器时,最大连接数 03 nginx作为反向代理服务器时,能够服务的最大连接数:(Worker 进程数量 x 单个 Worker 进程的最大连接数)/ 2。 04 nginx反向代理时,会建立client的链接和后端webserver 的链接,占用2个链接。 思考: 每打开一个socket占用一个fd 为什么,一个进程能够打开的fd数量有限制?io模型:
场景: 处理多个请求时,可以采用io多路复用或者阻塞io+多线程 io对路复用 一个线程,跟踪多个socket状态,那个就绪就读写那个; 阻塞io+多线程:每一个请求,新建一个服务线程思考:
io多路复用和多线程的使用场景?io多路复用 单个连接的请求处理速度没有优势
大并发量 只使用一个线程,处理大量的并发请求,降低上下文切换环境损耗,也不需要考虑并发问题,相对可以处理更多请求; 消耗更多的系统资源(不需要线程调度开销) 适用于长连接的情况(多线程模式长连接容易造成线程过多,造成频繁调度) 阻塞io+多线程:实现简单,可以不依赖系统调用。 每个线程,都需要时间和空间; 线程数量增长时,线程调度开销指数增长 select poll epoll三者之间的比较// select 系统调用 int select(int maxfdp,fd_set *readfds,fd_set *writefds,fd_set *errorfds,struct timeval *timeout); // poll 系统调用 int poll(struct pollfd fds[], nfds_t nfds, int timeout);
select:
查询 fd_set 中,是否有就绪的 fd,可以设定一个超时时间,当有 fd (File descripter) 就绪或超时返回; fd_set 是一个位集合,大小是在编译内核时的常量,默认大小为 1024 特点: 连接数限制,fd_set 可表示的 fd 数量太小了; 线性扫描:判断 fd 是否就绪,需要遍历一边 fd_set; 数据复制:用户空间和内核空间,复制连接就绪状态信息poll:
解决了连接数限制: poll 中将 select 中的 fd_set 替换成了一个 pollfd 数组 解决 fd 数量过小的问题 数据复制:用户空间和内核空间,复制连接就绪状态信息 epoll:event 事件驱动epoll:event 事件驱动
事件机制:避免线性扫描 为每个 fd,注册一个监听事件 fd 变更为就绪时,将 fd 添加到就绪链表 fd 数量:无限制(OS 级别的限制,单个进程能打开多少个 fd) select,poll,epoll: 1.I/O多路复用的机制; 2.I/O多路复用就通过一种机制,可以监视多个描述符,一旦某个描述符就绪(一般是读就绪或者写就绪),能够通知程序进行相应的读写操作。 3.监视多个文件描述符 4.但select,poll,epoll本质上都是同步I/O: 5.用户进程负责读写(从内核空间拷贝到用户空间),读写过程中,用户进程是阻塞的; 6.异步 IO,无需用户进程负责读写,异步IO,会负责从内核空间拷贝到用户空间Nginx 的并发处理能力
关于 Nginx 的并发处理能力
并发连接数,一般优化后,峰值能保持在 1~3w 左右。(内存和 CPU 核心数不同,会有进一步优化空间)
这是这篇文章的原出处:
转载地址:https://liushiya.blog.csdn.net/article/details/104240605 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!
发表评论
最新留言
很好
[***.229.124.182]2024年04月25日 18时19分22秒
关于作者
喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
【学习笔记】Android Activity
2019-04-30
【学习笔记】Android Fragments
2019-04-30
Android使用Retrofit_00_Getting Started
2019-04-30
Android使用Retrofit_01_OAuth2 + GitHub
2019-04-30
Django + REST学习笔记
2019-04-30
【转载】将Ubuntu16.04 中gedit在仅显示一个文件时显示文件名tab
2019-04-30
fstream 对象多次使用时注意clear
2019-04-30
调试 LenaCV 3D Camera (Linux)
2019-04-30
OpenCV杂记 - Mat in C++
2019-04-30
lnmp部署
2019-04-30
location区段
2019-04-30
nginx访问控制、基于用户认证、https配置
2019-04-30
用zabbix监控nginx
2019-04-30
SaltStack
2019-04-30
Jenkins 控制台输出中的奇怪字符
2019-04-30
Linux添加系统调用
2019-04-30