跳到主要内容

四、初探 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 进程发送信号一样了。