简要介绍Nginx进程模型

1 Nginx进程模型

nginx共有两种进程模型,即master和worker进程。master主进程管理worker进程。管理包含:

  • 接收来自外界的信号,向各worker进程发送信号;
  • 监控worker进程的运行状态,当worker进程退出后(异常情况下),会自动重新fork新worker进程。Work进程主要去处理用户请求。

worker进程可以在核心配置文件中配置成多个。

## ./conf/nginx.conf
worker_processes  6;

查看nginx进程
# ps -ef|grep nginx

管理员发送指令(stop/reload等)到master进程,master再将指令分发给每个woker进程执行。

  • woker进程竞争来自客户端的请求。woker收到关闭请求,在处理结束、连接释放后才能关闭。
  • worker进程间相互独立,相对线程更安全。
  • 一个请求,只可能在一个worker进程中处理,一个worker进程,不可能处理其它进程的请求。尽量保持worker进程数与机器cpu核数一致,减少进程上下文切换、CPU资源竞争、cache失效等问题。

2 Worker抢占机制

当客户端请求进来,worker进程竞争该连接的accept_mutex锁。

accept_mutex的意义:当一个新连接到达时,如果激活了accept_mutex,那么多个Worker将以串行方式来处理,其中有一个Worker会被唤醒,其他的Worker继续保持休眠状态;如果没有激活accept_mutex,那么所有的Worker都会被唤醒,不过只有一个Worker能获取新连接,其它的Worker会重新进入休眠状态,这就是「惊群问题」

对Nginx而言,一般来说,worker_processes会设置成CPU个数,所以最多也就几十个,即便发生惊群问题的话,影响相对也较小。

Nginx缺省(默认)激活了accept_mutex,是一种保守的选择。如果关闭了它,可能会引起一定程度的惊群问题,表现为上下文切换增多(sar -w)或者负载上升,但是如果你的网站访问量比较大,为了系统的吞吐量,我还是建议大家关闭它。

3 Nginx事件处理机制

传统服务器事件处理采用同步阻塞AIO机制(例如Apache),当客户端请求进来后,worker1处理请求,此时worker1会阻塞,无法处理其他请求。针对于高并发的场景,则需要生产大量的worker。

Nginx采用了Linux的epoll模型,异步非阻塞。单个worker可以同时处理几万个请求的,具体取决于CPU和内存。当多个client请求worker1,假设client1的请求阻塞,由于异步非阻塞机制,worker1仍可以去处理其他客户端请求。

events {
    # Linux默认使用epoll模型
    use epoll;
    # 设置每个worker允许最大客户端连接数
    worker_connections  1024;
}

为什么要尽量保持worker进程数与CPU核心数一致?

一个worker进程可以同时处理的请求数只受限于内存大小,而且在架构设计上,不同的worker进程之间处理并发请求时几乎没有同步锁的限制,worker进程通常不会进入睡眠状态,因此,当Nginx上的进程数与CPU核心数相等时(最好每一个worker进程都绑定特定的CPU核心),尽可能减少进程上下文切换,避免多个worker进程抢占CPU,以及缓存失效等问题

当worker_processes的值为auto时,nginx会自动检测当前主机的cpu核心数,并启动对应数量的worker进程。

work进程绑定某个CPU核心使用worker_cpu_affinity指令。

posted @ 2020-12-27 23:19  Awecoder  阅读(386)  评论(0编辑  收藏  举报