文章目录
11.1 master-worker 机制
11.1.1 master-worker 工作原理图
- 一个 master (进程) 管理多个 worker (进程)
11.1.2 一说 master-worker 机制
- 争抢机制示意图
- 一个 master Process 管理多个 worker process ,也就是说 Nginx 采用的是 多进程结构,而不是多线程结构
- 当 client 发出请求 (任务) 时,master Process 会通知管理的 worker process
- worker process 开始争抢任务,争抢到的 worker process 会开启连接,完成任务
- 每个 worker 都是一个独立的进程,每个进程里只有一个主线程
- Nginx 采用了 IO 多路复用机制 (需要在 Linux 环境) ,使用 IO 多路复用机制,是 Nginx 在使用为数不多的 worker process 就可以实现高并发的关键
11.1.3 二说 master-worker 机制
- Master-Worker 模式
1、Nginx 在启动后,会有一个 master 进程和多个相互独立的 worker 进程
2、Master 进程 接收来自外界的信号,向各 worker 进程发送信号,每个进程都有可能来处理这个连接
3、Master 进程能监控 Worker 进程的运行状态,当 worker 进程退出后(异常情况下),会自动启动新的 worker 进程
- accept_mutex 解决 “惊群现象”
1、所有子进程都继承了父进程的 sockfd,当连接进来时,所有子进程都将收到通知并 “争着” 与它建立连接,这就叫 “惊群现象”
2、大量的进程被激活又挂起,只有一个进程可以accept()
到这个连接,会消耗系统资源
3、Nginx 提供了一个 accept_mutex ,这是一个加在 accept 上的一把共享锁。即每个 worker 进程在执行 accept 之前都需要先获取锁,获取不到就放弃执行accept()
有了这把锁之后,同一时刻,就只会有一个进程去
accpet()
,就不会有惊群问题了
4、当一个 worker 进程在accept()
这个连接之后,就开始读取请求,解析请求,处理请求,产生数据后,再返回给客户端,最后才断开连接,完成一个完整的请求
5、一个请求,完全由 worker 进程来处理,而且只能在一个 worker 进程中处理
- 用多进程结构而不用多线程结构的好处
1、节省锁带来的开销,每个 worker 进程都是独立的进程,不共享资源,不需要加锁。在编程以及问题查找上,也会方便很多
2、独立进程,减少风险。采用独立的进程,可以让互相之间不会影响,一个进程退出后,其它进程还在工作,服务不会中断,master 进程则很快重新启动新的 worker 进程
- 实现高并发的秘密 - IO 多路复用
1、对于 Nginx 来讲,一个进程只有一个主线程,那么它是怎么实现高并发的呢?
2、采用了 IO 多路复用的原理,通过异步非阻塞的事件处理机制,epoll 模型,实现了轻量级和高并发
3、nginx 是如何具体实现的呢?
- 举例来说:每进来一个 request,会有一个 worker 进程去处理。但不是全程的处理,处理到什么程度呢?
- 处理到可能发生阻塞的地方,比如向上游 (后端) 服务器转发 request,并等待请求返回
- 那么,这个处理的 worker 不会这么傻等着,他会在发送完请求后,注册一个事件:“如果 upstream 返回了,告诉我一声,我再接着干”。于是他就休息去了
- 此时,如果再有 request 进来,他就可以很快再按这种方式处理
- 而一旦上游服务器返回了,就会触发这个事件,worker 才会来接手,这个 request 才会接着往下走
- 由于 web server 的工作性质决定了每个 request 的大部份生命都是在网络传输中,实际上花费在 server 机器上的时间片不多,这就是几个进程就能解决高并发的秘密所在
- 小结:Nginx 的 master-worker 工作机制的优势
1、支持
nginx -s reload
热部署,这个特征在前面我们使用过
2、对于每个 worker 进程来说,独立的进程,不需要加锁,所以省掉了锁带来的开销,同时在编程以及问题查找时,也会方便很多
3、每个 worker 都是一个独立的进程,但每个进程里只有一个主线程,通过异步非阻塞的方式 / IO 多路复用 来处理请求, 即使是高并发请求也能应对
4、采用独立的进程,互相之间不会影响,一个 worker 进程退出后,其它 worker 进程还在工作,服务不会中断,master 进程则很快启动新的 worker 进程
5、一个 worker 分配一个 CPU , 那么 worker 的线程可以把一个 cpu 的性能发挥到极致
11.2 参数设置
11.2.1 worker_processes
- 需要设置多少个 worker ?每个 worker 的线程可以把一个 cpu 的性能发挥到极致。所以 worker 数和服务器的 cpu 数相等是最为适宜的。设少了会浪费 cpu,设多了会造成 cpu 频繁切换上下文带来的损耗
- 设置 worker 数量,Nginx 默认没有开启利用多核 cpu,可以通过增加
worker_cpu_affinity
配置参数来充分利用多核 cpu 的性能
#2 核 cpu,开启 2 个进程
worker_processes 2;
worker_cpu_affinity 01 10;
#2 核 cpu,开启 4 个进程,
worker_processes 4;
worker_cpu_affinity 01 10 01 10;
#4 核 cpu,开启 2 个进程,0101 表示开启第一个和第三个内核,1010 表示开启第二个和第四个内核;
worker_processes 2;
worker_cpu_affinity 0101 1010;
#4 个 cpu,开启 4 个进程
worker_processes 4;
worker_cpu_affinity 0001 0010 0100 1000;
#8 核 cpu,开启 8 个进程
worker_processes 8;
worker_cpu_affinity 00000001 00000010 00000100 00001000 00010000 00100000 01000000 10000000;
worker_cpu_affinity
理解
11.2.1 worker_processes 配置实例
vim /usr/local/nginx/nginx.conf
,修改配置文件
- 重新加载 nginx ,
/usr/local/nginx/sbin/nginx -s reload
- 查看 nginx 的 worker process 情况
ps -ef | grep nginx
11.2.3 worker_connection
- worker_connection 表示每个 worker 进程所能建立连接的最大值,所以,一个 nginx 能建立的最大连接数,应该是 worker_connections * worker_processes① 默认:worker_connections: 1024 ② 调大:worker_connections: 60000(调大到 6 万连接) ③ 同时要根据系统的最大打开文件数来调整
- 系统的最大打开文件数>= worker_connections*worker_process
- 根据系统的最大打开文件数来调整,worker_connections 进程连接数量要小于等于系统的最大打开文件数
- worker_connections 进程连接数量真实数量= worker_connections * worker_process
- 查看系统的最大打开文件数:
ulimit -a | grep "open files"
- 根据最大连接数计算最大并发数:- 如果是支持 http1.1 的浏览器每次访问要占两个连接,所以普通的静态访问最大并发数是: worker_connections * worker_processes /2- 而如果是 HTTP 作为反向代理来说,最大并发数量应该是 worker_connections * worker_processes/4- 因为作为反向代理服务器,每个并发会建立与客户端的连接和与后端服务的连接,会各占用两个连接- 看一个示意图
11.2.4 配置 Linux 最大打开文件数
- 使用
ulimit -a
可以查看当前系统的所有限制值,使用ulimit -n
可以查看当前的最大打开文件数 - 新装的 linux 默认只有 1024,当作负载较大的服务器时,很容易遇到
error: too many open files
因此,需要将其改大 - 使用
ulimit -n 65535
可即时修改,但重启后就无效了 (注ulimit -SHn 65535
等效ulimit -n 65535
,-S 指 soft,-H 指 hard) - 有如下三种修改方式:① 在 /etc/rc.local 中增加一行
ulimit -SHn 65535
② 在 /etc/profile 中增加一行ulimit -SHn 65535
③ 在 /etc/security/limits.conf 最后增加如下两行记录,然后重启系统
* soft nofile 65535
* hard nofile 65535
- 注意:在 CentOS 中使用第 ① 种方式无效果,使用第 ③ 种方式有效果,而在 Debian 中使用第 ② 种有效果
- 如果重启系统,报内核错误,需要编辑 /etc/pam.d/login 配置文件,在最后添加以下一条内容:
vim /etc/pam.d/login
session required pam_limits.so
- 编辑完成,重启系统,就会发现最大文件数已经配置成功
版权归原作者 要学就学灰太狼 所有, 如有侵权,请联系我们删除。