Nginx原理
# 42.Nginx原理
讲解下Nginx内部的原理
# mater 和 worker的概念
启动Nginx进程后,我们发现Nginx其实是有2个进程的:
# ps -ef | grep nginx
root 14858 1 0 07:35 ? 00:00:00 nginx: master process ./nginx
nobody 14860 14858 0 07:35 ? 00:00:00 nginx: worker process
2
3
一个是master进程,一个是worker进程。Nginx是这样工作的:
- 首先启动一个master进程
- 然后启动一个或多个worker进程
- worker进程是用来工作的,也就是处理请求
- master进程则是用来管理worker的,将活分给worker进程

# master+worker机制如何工作
首先,一个请求来到了Nginx,那么master就要开始工作了
master告诉所有worker,有新的请求
然后worker是通过争抢的方式去处理这个请求
一个worker抢到请求后,会看情况是否需要转发给Tomcat,还是自己直接处理。

# 一个 master 和多个 woker 的好处
为什么Nginx要这样设计呢?因为这样有很多好处,例如:
- 首先,对于每个 worker 进程来说,独立的进程,不需要加锁,所以省掉了锁带来的开销,同时在编程以及问题查找时,也会方便很多。
- 采用独立的进程,可以让互相之间不会影响,一个进程退出后,其它进程还在工作,服务不会中断,master 进程则很快启动新的worker 进程。
- 如果有 worker 进程异常退出,会导致当前 worker 上的所有请求失败,但不影响到所有请求,降低了风险
- 可以使用 nginx -s reload 热部署,也就是不用重启Nginx也可以让新的配置生效:没有抢到请求进行处理的worker,会自己更新,而正在处理请求的worker进程不会停止处理请求,这样即使在热部署期间,Nginx还是在正常处理请求的。等处理完后再自己更新。
- ...........
# 需要设置多少个 worker
Nginx 同 redis 类似都采用了 IO 多路复用机制,每个 worker 都是一个独立的进程,但每个进程里只有一个主线程,通过异步非阻塞的方式来处理请求, 即使是千上万个请求也不在话下。
每个 worker 的线程可以把一个 cpu 的性能发挥到极致,所以 worker 数和服务器的 cpu数相等是最为适宜的。设少了会浪费 cpu,设多了会造成 cpu 频繁切换上下文带来的损耗。
注意,在Windows下的话则没有 IO多路复用机制,所以在Windows下,Nginx的性能会降低不少(Redis同理,最好安装到Linux下使用)
Nginx默认没有开启利用多核cpu,我们可以通过设置worker数量和设置worker_cpu_affinity配置参数来充分利用多核cpu的性能。配置实例:
2核CPU,开启2个进程
worker_processes 2;
worker_cpu_affinity 01 10;
2
# 连接数 worker_connection
这个值是设置每个 worker 进程所能建立连接的最大值。
worker_connections 1024
举个例子,一个请求发送过来,那么这个请求到worker进程之间有一个连接,并且worker到请求之间也有一个连接;
而如果这个请求涉及到转发给Tomcat处理,那么还得占用2个连接:worker进程到Tomcat之间占用一个,Tomcat进程到worker进程占用一个
┌─────────┐ ┌─────────┐ ┌─────────┐
│ │ ←─────── │ │ ─────→ │ │
│ Client │ │ Worker │ │ Tomcat │
│ │ │ │ │ │
│ │ ──────→ │ │ ←───── │ │
└─────────┘ └─────────┘ └─────────┘
2
3
4
5
6
综上,Nginx支持的最大并发数是多少得分类讨论:
- 普通的静态访问最大并发数是: (worker_connections × worker_processes) / 2
- 如果是 HTTP 作为反向代理来说,最大并发数量应该是 (worker_connections × worker_processes)/ 4
# 最后
通过前面的讲解,其实基本上够我们使用了,但有些时候学多一点,使用起来更得心应手,后续我们会介绍一些Nginx常用的配置,读者可以看情况阅读。