nginx的进程

526 阅读5分钟

一、进程结构

nginx有两种进程结构:多进程结构、单进程结构。

单进程结构的地址空间在线程之间是共享的,所以一旦有一个线程崩了,就会导致整个nginx不可用,所以默认的nginx都是多进程的,单进程只适合我们在本地开发时使用。

nginx多进程的结构如图1所示:

                                                               图1

  • master进程是主进程,它的作用是管理worker进程,主要是检测worker进程是否正常运行、是否需要重新启动配置文件、是否需要热部署等。master进程默认是允许加入第三方模块代码的,但是非常不建议这么做,因为一旦第三方模块出错,将会导致整个nginx不可用,
  • CM(Cache Manager):缓存的管理。周期性的启动,检查告诉缓存的状态,
  • CL(Cache Loader):缓存的载入。写入缓存时启动,写完关闭,时间很短。
  • Worker:Worker进程是真正用来处理请求的进程。缓存要在多个Worker进程之间共享,并且还要被CM、CL使用。

这些进程间的通信都是使用共享内存进行的。

二、为什么要有多个Worker进程

nginx采用事件驱动之后,希望每一个worker进程都对应一个CPU,所以worker进程要配置的和服务器上的CPU核数一致,并且每一个worker进程都要与某一个CPU进行绑定,这样可以更好的使用每一个CPU上面的CPU缓存。

master进程不消耗CPU。

三、多进程查看、操作

1、查看

启动nginx,使用ps -ef | grep nginx查看nginx进程,如图2所示,关于nginx的进程有两个,一个是master进程,一个是worker进程。

                                                                 图2

master进程的id为12492,worker进程的id为17355,worker进程的父进程为12492,即worker进程由master进程所创建。

2、reload

使用./sbin.nginx -s reload重新加载配置文件时,原来的worker进程会被关闭,master进程会新创建一个worker进程,该worker进程的id为17372。

                                                             图3

除了使用reload重新加载配置文件之外,我们还可以向master发送SIGHUP信号,通知master进程重新reload,比如我们使用kill -SIGHUP 12492,发送之后,我们查看nginx进程,如图4,发现原来17373的worker进程没有了,多了一个17405的worker进程。

                                                              图4

使用SIGHUP信号和reload的作用是一模一样的,都是优雅的关闭之前的worker进程。

3、SIGTERM

当我们使用SIGTERM关闭worker进程时,会先向master进程发送一个SIGCHILD信号,然后worker进程关闭,但是master进程会为了保持固定的worker进程数,再重新创建一个新的worker进程。

四、使用信号管理父子进程

在nginx中能够发送接收信号的有master进程、worker进程、nginx命令行。

1、master进程

a、监控worker进程

master进程能够启动worker进程,所以master进程会监控worker进程是否发送CHILD信号,当发送CHILD进程时,就说明worker进程将要关闭,那么master进程就会重新的拉起一个worker进程。

b、管理worker进程

master进程可以接收信号用来管理worker进程。

c、接收信号

  • TERM,INT:立刻停止worker进程。

  • QUIT:优雅的停止worker进程,也就是慢慢的停,要保证不会向用户发送立刻结束连接的报文。

  • HUP:重载配置文件。

  • USR1:重新打开日志文件。

  • USR2、WINCH:在热部署时使用到。

2、worker进程

同master进程的接收信号,但是不建议对worker进程发起信号,因为希望由master进程去管理worker进程。

3、nginx命令行

启动一个命令行后,nginx会将master进程的pid记录到logs/nginx.pid文件中,当我们使用nginx -s *这类命令行时,nginx的工具命令行会读取nginx.pid中的master的pid,然后想该pid发送HUP等信号。

所以直接使用reload等命令和使用kill发送信号的作用是一样的。

四、优雅的关闭

优雅的关闭就是慢慢的关闭,用户不会收到错误。

优雅的关闭主要针对的是HTTP请求,因为对于HTTP请求,nginx可以知道一个请求要经历多少的报文,才算是请求结束。

优雅的关闭的流程:

  • 设置一个定时器:worker_shutdown_timeout。

  • 关闭监听句柄,比如监听的是80端口,那么此时就会关闭80端口的监听句柄,不会在处理80端口的新的请求。

  • 关闭空闲的连接池,因为nginx为了保证对资源的利用是最大化的,会在连接池中保存一些空闲连接,并且这些连接没有断开,所以在这一步它会先关闭所有的空闲连接。

  • 在循环中等待全部连接关闭。在循环中,每当一个连接请求完毕,它就会关闭该连接。

  • 退出进程。当所有的请求都处理关闭时,会关闭进程;当worker_shutsown_timeout设置的时间到了,会关闭进程。

优雅的关闭时针对于HTTP请求的,其他的是没有办法进行优雅的关闭的,比如webscoket。