Nginx 是一个轻量级的HTTP 服务程序,相比其余服务器程序如Apache,Nginx占用内存少,稳定性高,并发处理能力强。同时Nginx 仍是一个反向代理服务程序,和邮件代理服务程序。Nginx具备丰富的模块库、灵活的配置、较低资源消耗等优势。下面,咱们一块儿深刻看一下Nginx的工做机制。nginx
咱们从如下几个方面说明如下:服务器
基于上面提到技术,以及Nginx不少地方的优化,让Nginx成为最快的HTTP服务器。网络
在Nginx的技术架构中,进程模型是相当重要的一部分。接下来,咱们一块儿看看Nginx进程模型,以及它们的工做机制。架构
Linux 系统中,Nginx默认以守护进程daemon方式启动,默认采用多进程方式。Nginx包括两种类型的进程:
- Master 进程,数量只有一个,管理Nginx自己和Worker进程
- Worker 进程,数量通常和CPU核数相等,Nginx的全部请求处理,均是在Worker进程中完成并发
下面,咱们分别深刻看一下Master和Worker进程。异步
在Nginx启动时,Master进程建立,主要负责初始化Nginx和相关模块、fork Worker进程、接收处理外界信号等工做。socket
咱们经过kill命令发送信号给Nignx Master 进程,看看Master进程如何处理:模块化
root@eg001:~# ps -ef | grep nginx | grep -v grep root 16533 1 0 Aug28 ? 00:00:00 nginx: master process nginx www-data 16534 16533 0 Aug28 ? 00:00:47 nginx: worker process www-data 16535 16533 0 Aug28 ? 00:00:51 nginx: worker process www-data 16536 16533 0 Aug28 ? 00:00:53 nginx: worker process www-data 16537 16533 0 Aug28 ? 00:00:51 nginx: worker process root@eg001:~# kill -HUP 16533 root@eg001:~# ps -ef | grep nginx | grep -v grep root 16533 1 0 Aug28 ? 00:00:00 nginx: master process nginx www-data 28194 16533 0 09:40 ? 00:00:00 nginx: worker process www-data 28195 16533 0 09:40 ? 00:00:00 nginx: worker process www-data 28196 16533 0 09:40 ? 00:00:00 nginx: worker process www-data 28197 16533 0 09:40 ? 00:00:00 nginx: worker process root@eg001:~#
分析流程:
- Master 进程接收到 HUP 信号
- Master 进程从新加载配置文件
- Master 进程启动新的Worker进程
- Master 进程发送信号给Worker 进程
- 老的Worker进程再也不接收新的请求
- 老的Worker进程处理完当前请求,退出
- 至此,Nginx完成平滑重启函数
注意:Nginx 0.8 版本之后,提供了 -s参数,用于管理Nginx服务的中止和重启,注意line 11:性能
root@eg001:~# nginx -h nginx version: nginx/1.1.19 Usage: nginx [-?hvVtq] [-s signal] [-c filename] [-p prefix] [-g directives] Options: -?,-h : this help -v : show version and exit -V : show version and configure options then exit -t : test configuration and exit -q : suppress non-error messages during configuration testing -s signal : send signal to a master process: stop, quit, reopen, reload -p prefix : set prefix path (default: /etc/nginx/) -c filename : set configuration file (default: /etc/nginx/nginx.conf) -g directives : set global directives out of configuration file
Worker进程负责全部请求的处理工做,咱们经过一个HTTP请求,来梳理一下Worker的工做流程:
- 新的请求到来:全部的Work进程的listenfd都会变得可读
- 竟抢互斥锁:全部 Worker 进程在注册listenfd读事件前,要先抢accept_mutex
- 抢到互斥锁的Worker,注册listenfd读事件,在事件中调用accept接受该链接
- 拿到请求后,Worker进程开始读取请求,解析请求,处理请求,产生数据,再返回给客户端
- Worker进程断开链接
须要注意:一个HTTP请求,彻底由Worker进程处理,并且只在一个Worker中处理
对于每一个Worker 进程来讲,独立的进程,不须要加锁,节约锁致使的资源开销;worker进程之间,互不干扰,平滑重启就是很好的例子,服务不中断。
Nginx 采用的是异步非阻塞事件处理机制,支持select/poll/epoll/kqueue 等等。Nginx 同时会监控多个事件,调用他们是阻塞的。可是调用有超时时间,在超时时间内,若是有事件准备好了,就返回,不然从新放入epoll中。当读写返回EAGAIN时,事件将会被再次放入epoll中。
处理线程只有一个,同时处理的请求也只有一个,所谓多请求并发,只是在不断的切换请求而已。虽然是切换,但这种切换不涉及上下文切换,相比十分轻量。更多的并发,只是会占用更多的内存。
进程相关的还有,信号和定时器,这部分另外单独讲解。
Nginx是模块化架构的服务,丰富的模块,松散耦合,也让Nginx更增强大!我看看Nginx 都有哪些模块
惊群效应:
- 当内核 accept 一个链接时,会唤醒全部等待中的进程
- 但实际上只有一个进程能获取链接,其余的进程都是被无效唤醒的
- 因此 Nginx 采用了自有的一套 accept 加锁机制,避免多个进程同时调用 accept
- Nginx 多进程的锁在底层默认是经过 CPU 自旋锁来实现。若是操做系统不支持自旋锁,就采用文件锁。