Nginx高并发依赖non-blocking I/O与异步回调在事件驱动架构中的深度协同:socket设为非阻塞是起点,epoll等事件循环监控就绪fd并分发,回调函数轻量执行且须可控生命周期,全链路垂直贯通实现单worker承载万级连接。

Nginx 的高并发能力不是靠堆线程或进程实现的,而是靠 non-blocking I/O 和 异步回调 在事件驱动架构中深度咬合——它们不是并列特性,而是同一套机制的两个不可分割的动作环节。
socket 层必须是非阻塞的
每个网络套接字在创建后立即被设为 non-blocking 模式(例如调用 fcntl(fd, F_SETFL, O_NONBLOCK))。这意味着:
- read()、write()、connect() 等系统调用会立刻返回,不会挂起 worker 进程
- 若数据未就绪或缓冲区满,返回 EAGAIN 或 EWOULDBLOCK,而不是等待
- 后续是否可读/可写,完全交由事件循环(如 epoll_wait)统一监控,不轮询、不睡眠
事件循环是调度中枢,不是执行体
epoll/kqueue 不直接运行业务逻辑,只负责告诉 worker:“哪些 fd 就绪了”。真正干活的是注册好的回调函数:
- 模块在发起 I/O 前,必须向事件循环注册回调(比如 ngx_http_read_request_handler)
- 内核只通知“fd 可读”,不执行任何用户代码;回调仍在线程上下文中由 worker 主动调用
- 事件循环拿到就绪列表后,把对应回调推入待执行队列,在当前事件周期末尾统一调度,避免重入和栈爆炸
回调函数要轻量、可重入、生命周期可控
每个回调只做一件事:处理当前就绪状态,并决定下一步动作。它不能阻塞,也不能长期持有资源:
- 处理完请求头后,若需读取请求体,应再次调用 ngx_add_timer 并重新注册读事件
- 遇到错误(如客户端断连、超时),必须显式调用 ngx_del_event 或 stream.destroy() 清理监听,释放闭包引用
- 第三方模块若引入同步 MySQL 查询或阻塞文件读写,会卡住整个 worker,拖垮所有连接
垂直贯通才是关键:从 socket 到模块层全链路协同
non-blocking 提供“不卡住”的可能性,事件循环提供“何时能动”的时机,回调机制提供“怎么动”的组合能力:
- socket 层设为 non-blocking 是起点,没有它,事件循环无从谈起
- 事件循环不调度阻塞操作,只分发就绪事件,确保单个 worker 能承载万级连接
- 模块通过回调嵌套形成状态机(如:接收→解析→转发→收响应→发回 client),每一步都可中断、可恢复、可取消


















