一、nginx 高并发原理
简单介绍:nginx 采用的是多进程(单线程) + io多路复用(epoll)模型 实现高并发
二、nginx 多进程
-
启动nginx
解析初始化配置文件后会 创建(fork)一个master进程 之后 这个进程会退出 master 进程会 变为孤儿进程 由init进程托管。(可以通过python 或php 启动后创建子进程,然后杀死父进程得见子进程会由init进程托管) 如下图可以看到nginx master 进程由init(ppid 为1 )进程管理。
-
master进程和worker进程
1、master 首先nginx 创建一个master 进程,通过socket() 创建一个sock文件描述符用来监听(sockfd) 绑定端口(bind) 开启监听(listen)。 nginx 一般监听80(http) 或 443 (https)端口 (fork 多个子进程后,master 会监听worker进程,和等待信号) 2、worker 然后 创建(fork)多个 worker子进程(复制master 进程的数据), 此时所有的worker进程 继承了sockfd(socket文件描述符), 当有连接进来之后 worker进程就可以accpet()创建已连接描述符, 然后通过已连接描述符与客户端通讯
-
惊群现象
由于worker进程 继承了master进程的sockfd,当连接进来是,所有的子进程都将收到通知并“争着”与 它建立连接,这就叫惊群现象。大量的进程被激活又挂起,最后只有一个进程accpet() 到这个连接,这会消耗系统资源 (等待通知,进程被内核全部唤醒,只有一个进程accept成功,其他进程又休眠。这种浪费现象叫惊群)
-
nginx 对惊群现象的处理
原因: 多个进程监听同一个端口引发的。 解决: 如果可以同一时刻只能有一个进程监听端口,这样就不会发生“惊群”了,此时新连接事件只能唤醒正在监听的唯一进程。 如何保持一个时刻只能有一个worker进程监听端口呢?nginx设置了一个accept_mutex锁,在使用accept_mutex锁是, 只有进程成功调用了ngx_trylock_accept_mutex方法获取锁后才可以监听端口 (linux 内核2.6 之后 不会出现惊群现象,只会有一个进程被唤醒)
-
代码简单理解