01-Nginx核心架构与工作原理:进程模型、并发处理、适配高并发售货柜业务

📅 2026/8/22 21:16:39
01-Nginx核心架构与工作原理:进程模型、并发处理、适配高并发售货柜业务
01-Nginx核心架构与工作原理进程模型、并发处理、适配高并发售货柜业务作者黒漂技术佬系列专栏Nginx高可用部署与三端项目实战一、Nginx是什么一句话先立住人设Nginx 是一个用 C 语言写成的高性能 HTTP 服务器和反向代理服务器同时还能干邮件代理IMAP/POP3和 TCP/UDP 代理的活儿。说人话它是你服务器机房里那个前台保安兼调度员所有从外面打过来的 HTTP 请求都先到它这儿报到它再按规矩把请求分发给后面真正干活的微服务。为什么整个互联网都在用它因为它有三个别人比不了的优点快单机几万甚至十几万并发连接不在话下省内存占用极低一万并发连接撑死吃十几兆内存稳配置改完reload一下就行不用停服在线上就是命二、为什么Nginx这么快核心就是进程模型事件驱动要理解 Nginx 为什么快得先看看它的老前辈 Apache 是怎么干活的。Apache 的传统模型一个请求一个线程Apache 默认用的是prefork 模式——每来一个连接就 fork 一个进程来伺候。后来进化出worker 模式改成一个连接一个线程。但不管怎么变本质都是一个请求独占一个执行单元。问题来了这个执行单元大部分时间在干嘛——在等。等网络数据从网卡到内核等用户把请求体发完等后端把响应吐回来。这个等的过程中线程是占着茅坑不拉屎的白白占着内存和 CPU 调度资源。并发一上来几千个线程同时在那儿傻等CPU 光在上下文切换上就累得够呛哪还有力气处理真正的业务。这就是 Apache 在高并发下被 Nginx 秒杀的根本原因。Nginx 的破局思路别傻等去干别的Nginx 的核心哲学就一句话IO 等待的时间绝不能浪费必须用来处理别的连接。怎么做到的靠的是两板斧Master-Worker 进程模型——少量进程管大量连接事件驱动 epoll——一个进程同时盯着一万个连接谁有数据就处理谁下面把这两板斧拆开讲透。三、Master-Worker 进程模型详解Nginx 启动后内存里会有一堆进程但角色分得很清楚[rootnginx ~]# ps -ef | grep nginx root 1234 1 0 10:00 ? 00:00:00 nginx: master process /usr/local/nginx/sbin/nginx nginx 1235 1234 0 10:00 ? 00:00:00 nginx: worker process nginx 1236 1234 0 10:00 ? 00:00:00 nginx: worker process nginx 1237 1234 0 10:00 ? 00:00:00 nginx: worker process nginx 1238 1234 0 10:00 ? 00:00:00 nginx: worker process1. Master 进程老板只管不干活Master 进程是 Nginx 的大管家由 root 用户启动因为要绑 80 端口这种特权端口。它自己不处理任何业务请求专门干管理上的活儿启动时读取nginx.conf校验配置合法性创建、监控、管理一堆 Worker 进程接收外部信号reload重载配置、reopen重开日志、stop优雅停止、quit立即停止当 Worker 挂了Master 负责重新拉起一个补上为什么设计成 Master 不干活因为老板要是亲自下场搬砖万一搬砖搬崩了整个 Nginx 就全挂了。职责隔离——管理进程不碰业务请求业务进程挂了有大管家兜底重启这才是高可用的根基。2. Worker 进程打工人干所有的活Worker 进程是真正干活的。有几个 Worker 由worker_processes配置决定通常设置为等于 CPU 核心数比如 4 核就开 4 个 Worker。每个 Worker 进程内部维护一个连接池能同时处理大量连接。关键点来了——Worker 之间是平等的、独立的、竞争式的它们共享同一份监听 socket由 Master 创建并 fork 继承新连接进来时多个 Worker 通过竞争 accept机制抢着处理抢到哪个 Worker 处理后续这个连接的读写都由它负责全程不会被别的 Worker 插手这种多个平等打工人抢活干的设计天然就是负载均衡——谁闲谁接活不用老板操心分配。┌──────────────────┐ 客户端请求 ──────▶│ Master 进程 │ (只管理不接客) │ (root 用户) │ └────────┬─────────┘ │ fork 监控 ┌──────────────┼──────────────┐ ▼ ▼ ▼ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ Worker 1 │ │ Worker 2 │ │ Worker N │ │ (nginx) │ │ (nginx) │ │ (nginx) │ │ 万级连接 │ │ 万级连接 │ │ 万级连接 │ └──────────┘ └──────────┘ └──────────┘为什么要用多进程而不是多线程这是 Nginx 设计的精妙之处进程隔离更稳一个 Worker 出 bug 崩了别的 Worker 照常工作对外几乎无感知避免锁竞争多线程共享内存得加锁锁在高并发下是性能毒药多进程各自独立内存无锁无争用C 语言没有语言级并发安全保护多进程模型规避了 C 在多线程并发上的坑简单可靠四、事件驱动与 epoll 机制Worker 进程能同时管几万个连接靠的就是事件驱动。打个比方Apache 的做法像给每个客人配一个服务员服务员得全程陪着客人想一会儿说一句话服务员就傻站着等。Nginx 的做法像一个大堂经理同时盯着大厅里几万个客人谁举手了有数据到了就过去处理谁处理完立马回前台继续盯着。盯着几万个客人这个动作在 Linux 下靠的是epoll系统调用。select/poll 的痛点每次都全量扫描早期的 IO 多路复用用select或poll机制是每次调用都把所有监听的 socket 全量告诉内核内核遍历一遍看哪些有事件再返回。连接数一多这个遍历就是 O(n) 的灾难——一万连接每次都扫一遍CPU 直接累趴。epoll 的破局回调机制谁有事通知谁epoll 是 Linux 2.6 引入的三个核心 APIepoll_create创建一个 epoll 实例内核里维护一棵红黑树一个就绪链表epoll_ctl把要监听的 socket 注册进去红黑树插入节点epoll_wait阻塞等待只有就绪的连接才会被返回关键在 epoll 内部用了回调机制每个注册的 socket 在内核里挂了个回调网卡收到数据触发硬件中断后内核把该 socket 对应的回调一调把这个 socket 塞进就绪链表。epoll_wait返回时直接拿就绪链表里的内容——活跃连接有多少返回多少跟总连接数无关复杂度是 O(活跃数)。这就是 Nginx 单个 Worker 能扛几万甚至十万连接的底层密码连接再多真正活跃的就那一小撮epoll 只处理活跃的不浪费 CPU。五、异步非阻塞 IOepoll 解决了高效感知哪个连接有事接下来是处理这个事。Apache 的同步模型处理一个请求时调后端、读文件、写响应全程阻塞在当前线程上干等结果回来。Nginx 的异步非阻塞模型处理请求时不会傻等。比如反向代理到后端 TomcatNginx 发出请求后立刻返回去处理别的连接等后端响应到了epoll 会再次通知 Nginx “这条连接有数据可读了”Nginx 才回来接着处理。这种事件来了我处理事件没来我去管别人的模式让 Worker 进程的 CPU 利用率拉满全程几乎没有傻等的空转。六、连接数与并发处理能力Nginx 的并发能力由两个配置项决定worker_processesWorker 进程数一般等于 CPU 核数或设auto自动匹配worker_connections每个 Worker 能同时持有的最大连接数默认 1024生产环境常调到 10240 或更高理论上最大并发 worker_processes × worker_connections。比如 4 核机器配worker_connections 10240理论并发 40960。但要注意一个细节Nginx 作为反向代理时每个客户端连接会对应一条到后端的连接所以实际可服务的客户端连接数大约是worker_processes × worker_connections / 2还要留一部分给其他用途。调大worker_connections时操作系统层面的文件描述符限制ulimit -n也得跟着调大不然 Nginx 会报accept() failed (24: Too many open files)这种错。七、无人售货柜高并发场景为什么选 Nginx回到业务。无人售货柜有典型的早高峰/午高峰流量尖刺早 7:30-9:00 写字楼附近几百台柜子几万用户同时扫码开门午 11:30-13:00 同一波高峰外加订单生成、支付回调集中爆发三端流量都汇聚到同一套后端小程序、安卓工控设备、SaaS 管理后台这种场景下选 Nginx 的理由扛尖刺高峰期瞬时几万 QPSNginx 单机轻松扛住不至于在网关层就成瓶颈省资源部署在云服务器上内存占用十几兆相比 Java 网关动辄几百兆省钱省实例三端统一入口小程序 HTTPS 接口、设备 WebSocket 长连接、后台静态资源全在 Nginx 一层搞定路由分发优雅热重载业务配置改了nginx -s reload瞬间生效连接不中断凌晨不用熬夜发版稳定性极强C 写的单体二进制没有 JVM 那种 GC 停顿和内存泄漏烦恼常年轻松跑满 99.99% 可用率一句话无人售货柜要的是高并发下不抖、不卡、不贵Nginx 在网关这层就是最优解。八、小结这一篇我们把 Nginx 拆解到了骨子里从 Apache 的一请求一线程痛点到 Nginx 的 Master-Worker 进程模型职责隔离从 epoll 回调机制解决万连接高效感知到异步非阻塞让 CPU 不空转最后落到无人售货柜早高峰场景说清了为什么这个业务必须把 Nginx 放在流量第一层。后面几篇我们会基于这套架构把三端流量设计、环境搭建、配置实战一步步展开。