全站流量的总闸门。 浏览器最终不应知道你的API容器端口
Nginx启动后会有一个master进程和若干个worker进程(默认等于CPU核数)。 每个 worker 单线程 + 非阻塞 IO(epoll),一个线程处理成千上万个连接。
对比 Apache 的 prefork 模型:Apache 每个连接一个进程/线程,1 万并发就要 1 万个线程,每个线程栈 8MB,光内存就 80GB,还有大量上下文切换开销。Nginx 用事件驱动,一个线程用 epoll 同时监听 1 万个 socket,只有真正有数据可读写的才处理,其余时间都在 epoll_wait 上等——内存占用几乎不变。
Nginx其实就是类似Android中Handler/Looper模型 与 每请求一个线程的区别。
Nginx的worker 约等于 一个Looper线程:所有连接都是注册在epoll上的事件源,就绪了就产生一个消息,worker处理完继续loop。
这也是为什么Nginx配置里绝对不能写堵塞操作(比如同步调用外部接口) -- 一个worker卡住,它负责的上万个链接全部卡住。
但是Apache prefork 约等于每次请求都Thread().start():简单直观,但是线程数一多就崩。
| 算法 | 原理 | 适用 |
|---|---|---|
round-robin(默认) |
按顺序轮流 | 实例配置相同、请求耗时均匀 |
least_conn |
给当前连接数最少的 | 请求耗时差异大(推荐默认用这个) |
ip_hash |
按客户端 IP 哈希,同一 IP 固定到同一台 | 需要会话粘性(但更好的做法是 session 存 Redis) |
hash $request_uri |
按 URL 哈希 | 提高缓存命中率 |
random two |
随机挑两个,选连接少的 | 大规模集群,避免所有节点同步状态 |
健康检查:开源版 Nginx 只有被动检查(max_fails / fail_timeout)——请求失败了才标记为不可用。商业版(Nginx Plus)和 OpenResty 有主动检查。这就是为什么 K8s 里要用 readinessProbe 而不是靠 Nginx 判断:让编排层负责健康,Nginx 只管转发。
Nginx 之于服务端,非常像 你 App 里的「统一网络层 + 拦截器 + 缓存 + 重试」,只是它作用在服务端入口:
静态资源服务 ≈ 本地 assets 读取;
反向代理 ≈ Retrofit 的 baseUrl 转发;
负载均衡 ≈ 多域名/IP 容灾切换;
限流 ≈ 客户端的请求节流(但服务端限流是保护自己,客户端节流是保护别人);
try_files ≈ 资源找不到时回退到默认页(类似 Android 的 placeholder / error drawable)。