Nginx 的设计哲学是事件驱动 + 异步非阻塞 + 模块化,这让它在单机上轻松处理数十万并发连接,内存占用极低,CPU 利用率极高。
进程模型(Master + Worker + 辅助进程)
Nginx 启动后会产生以下进程:

- Master 进程(1 个,通常 root 启动)
- 读取、解析、校验 nginx.conf
- 根据配置 fork 出 Worker 进程
- 绑定监听端口(listen)
- 管理 Worker:监控存活、优雅 reload、平滑升级、接收信号(HUP、TERM 等)
- 不处理任何客户端请求,只做“管理者”角色
- reload 时:启动新 Worker 加载新配置 + 新 Lua 代码,旧 Worker 优雅退出(继续处理已有连接)
- Worker 进程(默认等于 CPU 核数,可手动设置
worker_processes auto;)- 每个 Worker 是单线程的事件循环(event loop)
- 使用操作系统最高效的 I/O 多路复用机制:
- Linux → epoll
- BSD/macOS → kqueue
- Windows → IOCP
- 所有连接(监听 socket + 已建立连接)都在同一个线程里通过事件通知异步处理
- 一个 Worker 可以同时持有几万到几十万连接(取决于
worker_connections)
- 辅助进程(可选,由 Master 启动)
- Cache Loader:Nginx 启动时把磁盘上的缓存元数据加载到内存(只运行一次)
- Cache Manager:定期清理过期缓存文件、检查磁盘空间
- (OpenResty 中还可能有 Lua JIT 相关辅助进程)
事件驱动异步非阻塞机制(核心竞争力)
- 每个 Worker 只用一个线程,通过 epoll 等监听成千上万的文件描述符(fd)。
- 当某个连接有事件(可读、可写、超时、关闭)时,内核通知 Worker,Worker 立刻切换处理。
- 网络 I/O、磁盘 I/O、后端代理等全部异步:不会阻塞 Worker 线程。
- 这就是 Nginx 能同时服务百万连接的原因——没有上下文切换开销,没有线程争抢锁。
模块化架构
Nginx 几乎所有功能都由模块实现,编译时可静态/动态加载:
- 核心模块:events、http、stream、mail 等
- HTTP 模块:ngx_http_core_module、ngx_http_proxy_module、ngx_http_upstream_module、ngx_http_ssl_module、ngx_http_gzip_module…
- 第三方模块:OpenResty 的 LuaJIT、lua-resty-*、ngx_lua 等
- Lua 代码(content_by_lua_file、access_by_lua 等)其实是运行在 ngx_lua 模块的上下文里,reload 时新 Worker 会重新加载 Lua 脚本(结合你之前问的 Lua 热更新问题)。
配置加载与零宕机 reload(与 Lua 结合)
- Master 读取 nginx.conf → 解析所有块 → fork 新 Worker
- 新 Worker 加载新配置 + 重新编译缓存所有 Lua 代码
- 旧 Worker 停止接受新连接,但处理完手中所有请求后才退出 → Lua 修改后 reload 完全零宕机,正在进行的连接不会断开(除非你设置了很短的 worker_shutdown_timeout)
Nginx 配置结构与主要常用字段参数
Nginx 配置是分层块结构,从外到内层层继承(内层可覆盖外层):
main(全局)
├── events { ... }
├── http {
│ ├── upstream { ... }
│ ├── server { ← 虚拟主机
│ │ ├── listen
│ │ ├── server_name
│ │ └── location / { ← 匹配 URI
│ │ ├── proxy_pass
│ │ ├── proxy_set_header
│ │ └── ...
│ │ }
│ └── ...
}
└── stream { ... } ← TCP/UDP 代理(可选)
最常用参数分类
全局 / 进程相关(main 上下文)
| 参数 | 作用 | 推荐生产值 |
|---|---|---|
| worker_processes | Worker 数量 | auto(等于 CPU 核数) |
| worker_rlimit_nofile | 每个 Worker 最大打开文件数 | 65535 或更高 |
| worker_connections | 每个 Worker 最大连接数 | 16384 ~ 65535 |
| worker_shutdown_timeout | 优雅退出超时(旧 Worker) | 10s |
events 块(事件机制)
events {
use epoll; # Linux 默认最好
worker_connections 32768;
multi_accept on; # 一次 accept 多个连接
}
http 块(HTTP 相关全局设置)
| 参数 | 作用 | 常用值 |
|---|---|---|
| sendfile on | 零拷贝发送静态文件 | on |
| tcp_nopush on | 结合 sendfile,减少小包 | on |
| tcp_nodelay on | 实时性要求高的场景 | on |
| keepalive_timeout | 客户端 keep-alive 超时 | 65s |
| client_max_body_size | 最大上传大小 | 100m |
| proxy_cache_path | 定义缓存目录(生产必配) | /var/cache/nginx levels=1:2 keys_zone=… |
server 块(虚拟主机)
| 参数 | 作用 | 示例 |
|---|---|---|
| listen | 监听端口 + 协议 | 443 ssl http2; 80; |
| server_name | 域名匹配 | example.com www.example.com; |
| ssl_certificate / ssl_certificate_key | HTTPS 证书 | /path/to/fullchain.pem; |
location 块(最常用转发配置)
location /api/ {
proxy_pass <http://backend>;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_buffering on; # 静态接口开,SSE 关
proxy_read_timeout 60s;
}
upstream 块(负载均衡)
upstream backend {
least_conn; # 或 ip_hash, hash $arg_token consistent;
server backend1:8080 weight=5;
server backend2:8080 max_fails=3 fail_timeout=30s;
keepalive 32; # 重要!后端连接池
}