NingG +

Nginx 系列:Nginx 原理

基本原理

Nginx 的进程模型

Nginx 服务器,正常运行过程中:

  1. 多进程:一个 Master 进程、多个 Worker 进程
  2. Master 进程:管理 Worker 进程
    1. 对外接口:接收外部的操作(信号)
    2. 对内转发:根据外部的操作的不同,通过信号管理 Worker
    3. 监控:监控 worker 进程的运行状态,worker 进程异常终止后,自动重启 worker 进程
  3. Worker 进程:所有 Worker 进程都是平等的
    1. 实际处理:网络请求,由 Worker 进程处理;
    2. Worker 进程数量:在 nginx.conf 中配置,一般设置为核心数,充分利用 CPU 资源,同时,避免进程数量过多,避免进程竞争 CPU 资源,增加上下文切换的损耗。

思考:

  1. 请求是连接到 Nginx,Master 进程负责处理和转发?
  2. 如何选定哪个 Worker 进程处理请求?请求的处理结果,是否还要经过 Master 进程?

HTTP 连接建立和请求处理过程:

  1. Nginx 启动时,Master 进程,加载配置文件
  2. Master 进程,初始化监听的 socket
  3. Master 进程,fork 出多个 Worker 进程
  4. Worker 进程,竞争新的连接,获胜方通过三次握手,建立 Socket 连接,并处理请求

Nginx 高性能、高并发:

  1. Nginx 采用:多进程 + 异步非阻塞方式(IO 多路复用 epoll)
  2. 请求的完整过程:
    1. 建立连接
    2. 读取请求:解析请求
    3. 处理请求
    4. 响应请求
  3. 请求的完整过程,对应到底层,就是:读写 socket 事件

Nginx 的事件处理模型

request:Nginx 中 http 请求。

基本的 HTTP Web Server 工作模式:

  1. 接收请求:逐行读取请求行请求头,判断段有请求体后,读取请求体
  2. 处理请求
  3. 返回响应:根据处理结果,生成相应的 HTTP 请求(响应行响应头响应体

Nginx 也是这个套路,整体流程一致。

模块化体系结构

nginx的模块根据其功能基本上可以分为以下几种类型:

常见问题剖析

Nginx vs. Apache

nginx vs. apache:

网络 IO 模型:

  1. nginx:IO 多路复用,epoll(freebsd 上是 kqueue )
    1. 高性能
    2. 高并发
    3. 占用系统资源少
  2. apache:阻塞 + 多进程/多线程
    1. 更稳定,bug 少
    2. 模块更丰富

参考:https://www.zhihu.com/question/19571087

场景:

处理多个请求时,可以采用:IO 多路复用 或者 阻塞 IO +多线程

  1. IO 多路服用一个 线程,跟踪多个 socket 状态,哪个就绪,就读写哪个;
  2. 阻塞 IO + 多线程:每一个请求,新建一个服务线程

思考IO 多路复用多线程 的适用场景?

Nginx 最大连接数

基础背景:

  1. Nginx 是多进程模型,Worker 进程用于处理请求;
  2. 单个进程的连接数(文件描述符 fd),有上限(nofile):ulimit -n
  3. Nginx 上配置单个 worker 进程的最大连接数:worker_connections 上限为 nofile
  4. Nginx 上配置 worker 进程的数量:worker_processes

因此,Nginx 的最大连接数:

  1. Nginx 的最大连接数:Worker 进程数量 x 单个 Worker 进程的最大连接数
  2. 上面是 Nginx 作为通用服务器时,最大的连接数
  3. Nginx 作为反向代理服务器时,能够服务的最大连接数:(Worker 进程数量 x 单个 Worker 进程的最大连接数)/ 2。
  4. Nginx 反向代理时,会建立 Client 的连接后端 Web Server 的连接,占用 2 个连接

思考:

  1. 每打开一个 socket 占用一个 fd
  2. 为什么,一个进程能够打开的 fd 数量有限制?

附录

HTTP 请求和响应

IO 模型

场景:

处理多个请求时,可以采用:IO 多路复用 或者 阻塞 IO +多线程

  1. IO 多路服用一个 线程,跟踪多个 socket 状态,哪个就绪,就读写哪个;
  2. 阻塞 IO + 多线程:每一个请求,新建一个服务线程

思考:IO 多路复用多线程 的适用场景?

select/poll 和 epoll 比较

详细内容,参考:

select/poll 系统调用:

// select 系统调用
int select(int maxfdp,fd_set *readfds,fd_set *writefds,fd_set *errorfds,struct timeval *timeout); 

// poll 系统调用
int poll(struct pollfd fds[], nfds_t nfds, int timeout);

select

poll

epoll: event 事件驱动

select,poll,epoll:

  1. I/O多路复用的机制;
  2. I/O多路复用就通过一种机制,可以监视多个描述符,一旦某个描述符就绪(一般是读就绪或者写就绪),能够通知程序进行相应的读写操作。
    1. 监视多个文件描述符
  3. 但select,poll,epoll本质上都是同步I/O
    1. 用户进程负责读写(从内核空间拷贝到用户空间),读写过程中,用户进程是阻塞的;
    2. 异步 IO,无需用户进程负责读写,异步IO,会负责从内核空间拷贝到用户空间

Nginx 的并发处理能力

关于 Nginx 的并发处理能力:

更多细节,参考:

参考资料

原文地址:https://ningg.top/nginx-series-principle/
微信公众号 ningg, 联系我

同类文章:

微信搜索: 公众号 ningg, 联系我, 交个朋友.

Top