【搞定Nginx高并发原理:多进程单线程和多路IO复用模型】
![搞定Nginx高并发原理:多进程单线程和多路IO复用模型](http://img.jiangsulong.com/220409/041U41146-0.jpg)
文章插图
Nginx现在是非常火爆的web服务器,她使用更少的资源,支持更多的并发连接数,实现了linux的epoll模型 。
Nginx采用的是多进程单线程和多路IO复用模型 。使用了I/O多路复用技术的Nginx,就成了”并发事件驱动“的服务器 。这里再强调下重点,
- 多进程单线程
- 多路IO复用模型
![搞定Nginx高并发原理:多进程单线程和多路IO复用模型](http://img.jiangsulong.com/220409/041U430L-1.jpg)
文章插图
一、多进程单线程Nginx 自己实现了对epoll的封装,是多进程单线程的典型代表 。使用多进程模式,不仅能提高并发率,而且进程之间是相互独立的,一 个worker进程挂了不会影响到其他worker进程 。
master进程管理worker进程:
- 接收来自外界的信号 。
- 向各worker进程发送信号 。
- 监控woker进程的运行状态 。
- 当woker进程退出后(异常情况下),会自动重新启动新的woker进程 。
二、IO 多路复用模型 epoll多路复用,允许我们只在事件发生时才将控制返回给程序,而其他时候内核都挂起进程,随时待命 。
epoll通过在Linux内核中申请一个简易的文件系统(文件系统一般用B+树数据结构来实现),其工作流程分为三部分:
- 调用 int epoll_create(int size)建立一个epoll对象,内核会创建一个eventpoll结构体,用于存放通过epoll_ctl()向epoll对象中添加进来的事件,这些事件都会挂载在红黑树中 。
- 调用 int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event) 在 epoll 对象中为 fd 注册事件,所有添加到epoll中的事件都会与设备驱动程序建立回调关系,也就是说,当相应的事件发生时会调用这个sockfd的回调方法,将sockfd添加到eventpoll 中的双链表 。
- 调用 int epoll_wait(int epfd, struct epoll_event * events, int maxevents, int timeout) 来等待事件的发生,timeout 为 -1 时,该调用会阻塞知道有事件发生 。
epoll()在中内核维护一个链表,epoll_wait直接检查链表是不是空就知道是否有文件描述符准备好了 。顺便提一提,epoll与select、poll相比最大的优点是不会随着sockfd数目增长而降低效率,使用select()时,内核采用轮训的方法来查看是否有fd准备好,其中的保存sockfd的是类似数组的数据结构fd_set,key 为 fd,value为0或者1(发生时间) 。
能达到这种效果,是因为在内核实现中epoll是根据每 sockfd 上面的与设备驱动程序建立起来的回调函数实现的 。那么,某个sockfd上的事件发生时,与它对应的回调函数就会被调用,将这个sockfd加入链表,其他处于“空闲的”状态的则不会 。在这点上,epoll 实现了一个"伪"AIO 。
可以看出,因为一个进程里只有一个线程,所以一个进程同时只能做一件事,但是可以通过不断地切换来“同时”处理多个请求 。
例子:Nginx 会注册一个事件:“如果来自一个新客户端的连接请求到来了,再通知我”,此后只有连接请求到来,服务器才会执行 accept() 来接收请求 。又比如向上游服务器(比如 php-FPM)转发请求,并等待请求返回时,这个处理的 worker 不会在这阻塞,它会在发送完请求后,注册一个事件:“如果缓冲区接收到数据了,告诉我一声,我再将它读进来”,于是进程就空闲下来等待事件发生 。
这样,基于 多进程+epoll,Nginx 便能实现高并发 。
三、worker进程工作流程当一个 worker 进程在 accept() 这个连接之后,就开始读取请求,解析请求,处理请求,产生数据后,再返回给客户端,最后才断开连接,一个完整的请求 。一个请求,完全由worker进程来处理,而且只会在一个worker进程中处理 。优点:
- 节省锁带来的开销 。每个worker进程都彼此独立地工作,不共享任何资源,因此不需要锁 。同时在编程以及问题排查上时,也会方便很多 。
- 独立进程,减少风险 。采用独立的进程,可以让互相之间不会影响,一个进程退出后,其它进程还在工作,服务不会中断,master进程则很快重新启动新的worker进程 。当然,worker进程自己也能发生意外退出 。
推荐阅读
- Nginx记录日志到systemd journal
- 对高并发流量控制的一点思考
- 办室主任经验十条,教你搞定工作
- 花草茶助你轻松搞定6个身体小问题
- 你必需知道的10个 Nginx 常用命令
- 高并发服务器架构--SEDA架构分析
- 一文搞懂高并发性能指标:QPS、TPS、RT、吞吐量
- 教你使用nginx部署网站教程
- nginx配置实例-反向代理
- Nginx基础知识从小白到入门