浅谈Nginx服务器的内部核心架构设计

前言

Nginx 是一个 免费的开源的高性能HTTP 服务器和 反向代理,以及 IMAP / POP3 代理服务器。 Nginx 以其高性能,稳定性,丰富的功能,简单的配置和低资源消耗而闻名。Nginx是一个 Web 服务器,也能够用做 反向代理负载均衡器HTTP 缓存编程

不少高知名度的网站都使用 Nginx,如:NetflixGitHubSoundCloudMaxCDN 等。windows

正文

1. Nginx的总体架构

1.1. 主进程

Nginx 启动时,会生成两种类型的 进程*,一个是 主进程master),一个windows 版本的目前只有一个)或 多个工做进程worker)。主进程 并不处理网络请求,主要负责 调度工做进程,也就是图示的 3 项:加载配置启动工做进程非停升级。因此,Nginx 启动之后,查看操做系统的进程列表,咱们就能看到 至少有两个 Nginx 进程。后端

1.2. 工做进程

服务器实际 处理网络请求响应 的是 工做进程worker),在类 unix 系统上,Nginx 能够配置 多个 worker,而每一个 worker 进程 均可以同时处理 数以千计网络请求缓存

1.3. 模块化设计

Nginxworker 进程,包括 核心功能性模块核心模块 负责维持一个 运行循环run-loop),执行网络请求处理的 不一样阶段 的模块功能,好比:网络读写存储读写内容传输外出过滤,以及 将请求发往上游服务器 等。而其代码的 模块化设计,也使得咱们能够根据须要对 功能模块 进行适当的 选择修改,编译成具备 特定功能 的服务器。安全

1.4. 事件驱动模型

基于 异步及非阻塞事件驱动模型,能够说是 Nginx 得以得到 高并发高性能 的关键因素,同时也得益于对 LinuxSolaris 及类 BSD 等操做系统内核中 事件通知I/O 性能加强功能 的采用,如 kqueueepollevent ports服务器

1.5. 代理(proxy)设计

代理设计,能够说是 Nginx 深刻骨髓的设计,不管是对于 HTTP,仍是对于 FastCGIMemcacheRedis 等的网络请求或响应,本质上都采用了 代理机制。因此,Nginx 天生就是高性能的 代理服务器网络

2. Nginx的模块化设计

高度模块化 的设计是 Nginx 的架构基础。Nginx 服务器被分解为 多个模块,每一个模块就是一个 功能模块,只负责自身的功能,模块之间严格遵循 “高内聚,低耦合” 的原则。多线程

2.1. 核心模块

核心模块Nginx 服务器正常运行 必不可少 的模块,提供 错误日志记录配置文件解析事件驱动机制进程管理 等核心功能。架构

2.2. 标准HTTP模块

标准 HTTP 模块提供 HTTP 协议解析相关的功能,好比:端口配置网页编码设置HTTP 响应头设置 等等。并发

2.3. 可选HTTP模块

可选 HTTP 模块主要用于 扩展 标准的 HTTP 功能,让 Nginx 能处理一些特殊的服务,好比:Flash 多媒体传输、解析 GeoIP 请求、网络传输压缩安全协议 SSL 支持等。

2.4. 邮件服务模块

邮件服务模块 主要用于支持 Nginx邮件服务,包括对 POP3 协议、IMAP 协议和 SMTP 协议的支持。

2.5. 第三方模块

第三方模块 是为了扩展 Nginx 服务器应用,完成开发者自定义功能,好比:Json 支持、Lua 支持等。

3. Nginx的请求方式处理

Nginx 是一个 高性能Web 服务器,可以同时处理 大量的并发请求。它结合 多进程机制异步机制,异步机制使用的是 异步非阻塞方式,接下来就给你们介绍一下 Nginx多线程机制异步非阻塞机制

3.1. 多进程机制

服务器每当收到一个客户端时,就有 服务器主进程master process)生成一个 子进程worker process)出来和客户端创建链接进行交互,直到链接断开,该子进程就结束了。

使用 进程 的好处是 各个进程之间相互独立不须要加锁,减小了使用锁对性能形成影响,同时下降编程的复杂度,下降开发成本。其次,采用独立的进程,可让 进程互相之间不会影响,若是一个进程发生异常退出时,其它进程正常工做,master 进程则很快启动新的 worker 进程,确保服务不会中断,从而将风险降到最低。

缺点是操做系统生成一个 子进程 须要进行 内存复制 等操做,在 资源时间 上会产生必定的开销。当有 大量请求 时,会致使 系统性能降低

3.2. 异步非阻塞机制

每一个 工做进程 使用 异步非阻塞方式,能够处理 多个客户端请求

当某个 工做进程 接收到客户端的请求之后,调用 IO 进行处理,若是不能当即获得结果,就去 处理其余请求(即为 非阻塞);而 客户端 在此期间也 无需等待响应,能够去处理其余事情(即为 异步)。

IO 返回时,就会通知此 工做进程;该进程获得通知,暂时 挂起 当前处理的事务去 响应客户端请求

4. Nginx事件驱动模型

Nginx异步非阻塞机制 中,工做进程 在调用 IO 后,就去处理其余的请求,当 IO 调用返回后,会 通知工做进程。对于这样的系统调用,主要使用 Nginx 服务器的 事件驱动模型 来实现。

如上图所示,Nginx事件驱动模型事件收集器事件发送器事件处理器 三部分基本单元组成。

  • 事件收集器:负责收集 worker 进程的各类 IO 请求;

  • 事件发送器:负责将 IO 事件发送到 事件处理器

  • 事件处理器:负责各类事件的 响应工做

事件发送器 将每一个请求放入一个 待处理事件列表,使用非阻塞 I/O 方式调用 事件处理器 来处理该请求。其处理方式称为 “多路 IO 复用方法”,常见的包括如下三种:select 模型、poll 模型、epoll 模型。

5. Nginx进程处理模型

Nginx 服务器使用 master/worker 多进程模式。多线程启动和执行的流程以下:

  1. 主程序 Master process 启动后,经过一个 for 循环来 接收处理外部信号

  2. 主进程 经过 fork() 函数产生 worker 子进程,每一个 子进程 执行一个 for 循环来实现 Nginx 服务器 对事件的接收处理

通常推荐 worker 进程数CPU 内核数 一致,这样一来不存在 大量的子进程 生成和管理任务,避免了进程之间 竞争 CPU 资源进程切换 的开销。并且 Nginx 为了更好的利用 多核特性,提供了 CPU 亲缘性 的绑定选项,咱们能够将某 一个进程绑定在某一个核 上,这样就不会由于 进程的切换 带来 Cache 的失效。

对于每一个请求,有且只有一个 工做进程 对其处理。首先,每一个 worker 进程都是从 master 进程 fork 过来。在 master 进程里面,先创建好须要 listensocket(listenfd) 以后,而后再 fork 出多个 worker 进程。

全部 worker 进程的 listenfd 会在 新链接 到来时变得 可读,为保证只有一个进程处理该链接,全部 worker 进程在注册 listenfd 读事件抢占 accept_mutex,抢到 互斥锁 的那个进程 注册 listenfd 读事件,在 读事件 里调用 accept 接受该链接。

当一个 worker 进程在 accept 这个链接以后,就开始 读取请求解析请求处理请求,产生数据后,再 返回给客户端,最后才 断开链接,这样一个完整的请求就是这样的了。咱们能够看到,一个请求,彻底由 worker 进程来处理,并且只在一个 worker 进程中处理。

Nginx 服务器的运行过程当中,主进程工做进程 须要进程交互。交互依赖于 Socket 实现的 管道 来实现。

5.1. 主进程与工做进程交互

这条管道与普通的管道不一样,它是由 主进程 指向 工做进程单向管道,包含主进程向工做进程发出的 指令工做进程 ID 等;同时 主进程 与外界经过 信号通讯;每一个 子进程 具有 接收信号,并处理相应的事件的能力。

5.2. 工做进程与工做进程交互

这种交互是和 主进程-工做进程 交互是基本一致的,可是会经过 主进程 间接完成。工做进程 之间是 相互隔离 的,因此当工做进程 W1 须要向工做进程 W2 发指令时,首先找到 W2进程 ID,而后将正确的指令写入指向 W2通道W2 收到信号采起相应的措施。

小结

经过这篇文章,咱们对 Nginx 服务器的 总体架构 有了一个总体的认识。包括其 模块化的设计多进程异步非阻塞 的请求处理方式、事件驱动模型 等。经过这些理论知识,才能更好地领悟 Nginx 的设计思想。对于咱们学习 Nginx 来讲有很大的帮助。


欢迎关注技术公众号: 零壹技术栈

零壹技术栈

本账号将持续分享后端技术干货,包括虚拟机基础,多线程编程,高性能框架,异步、缓存和消息中间件,分布式和微服务,架构学习和进阶等学习资料和文章。

相关文章
相关标签/搜索