跳到主要内容

四、初探 Nginx 架构

初探 Nginx 架构​

众所周知,Nginx 性能高,而 Nginx 的高性能与其架构是分不开的。那么 Nginx 究竟是怎么样的呢?这一节我们先来初识一下 Nginx 框架吧。

Nginx 在启动后,在 unix 系统中会以 daemon 的方式在后台运行,后台进程包含一个 master 进程和多个 worker 进程。我们也可以手动地关掉后台模式,让 Nginx 在前台运行,并且通过配置让 Nginx 取消 master 进程,从而可以使 Nginx 以单进程方式运行。很显然,生产环境下我们肯定不会这么做,所以关闭后台模式,一般是用来调试用的,在后面的章节里面,我们会详细地讲解如何调试 Nginx。所以,我们可以看到,Nginx 是以多进程的方式来工作的,当然 Nginx 也是支持多线程的方式的,只是我们主流的方式还是多进程的方式,也是 Nginx 的默认方式。Nginx 采用多进程的方式有诸多好处,所以我就主要讲解 Nginx 的多进程模式吧。

刚才讲到,Nginx 在启动后,会有一个 master 进程和多个 worker 进程。master 进程主要用来管理 worker 进程,包含:接收来自外界的信号,向各 worker 进程发送信号,监控 worker 进程的运行状态,当 worker 进程退出后(异常情况下),会自动重新启动新的 worker 进程。而基本的网络事件,则是放在 worker 进程中来处理了。多个 worker 进程之间是对等的,他们同等竞争来自客户端的请求,各进程互相之间是独立的。一个请求,只可能在一个 worker 进程中处理,一个 worker 进程,不可能处理其它进程的请求。worker 进程的个数是可以设置的,一般我们会设置与机器cpu核数一致,这里面的原因与 Nginx 的进程模型以及事件处理模型是分不开的。Nginx 的进程模型,可以由下图来表示:

 

在Nginx 启动后,如果我们要操作 Nginx,要怎么做呢?从上文中我们可以看到,master 来管理 worker 进程,所以我们只需要与 master 进程通信就行了。master 进程会接收来自外界发来的信号,再根据信号做不同的事情。所以我们要控制 Nginx,只需要通过 kill 向 master 进程发送信号就行了。比如kill -HUP pid,则是告诉 Nginx,从容地重启 Nginx,我们一般用这个信号来重启 Nginx,或重新加载配置,因为是从容地重启,因此服务是不中断的。master 进程在接收到 HUP 信号后是怎么做的呢?首先 master 进程在接到信号后,会先重新加载配置文件,然后再启动新的 worker 进程,并向所有老的 worker 进程发送信号,告诉他们可以光荣退休了。新的 worker 在启动后,就开始接收新的请求,而老的 worker 在收到来自 master 的信号后,就不再接收新的请求,并且在当前进程中的所有未处理完的请求处理完成后,再退出。当然,直接给 master 进程发送信号,这是比较老的操作方式,Nginx 在 0.8 版本之后,引入了一系列命令行参数,来方便我们管理。比如,./nginx -s reload,就是来重启 Nginx,./nginx -s stop,就是来停止 Nginx 的运行。如何做到的呢?我们还是拿 reload 来说,我们看到,执行命令时,我们是启动一个新的 Nginx 进程,而新的 Nginx 进程在解析到 reload 参数后,就知道我们的目的是控制 Nginx 来重新加载配置文件了,它会向 master 进程发送信号,然后接下来的动作,就和我们直接向 master 进程发送信号一样了。