跳到主要内容
约 8 分钟7 张卡

Nginx 与负载均衡

Nginx 提供反向代理、HTTP 路由和负载均衡。本文负责连接模型、代理参数、LVS 模式与错误诊断。

1. 面试核心​

先记住这几条,再读正文

2. Nginx 的结构与常用配置​

master 读取配置并管理 worker。worker 通过事件循环处理已就绪的网络操作。worker_processes auto 根据可用 CPU 自动设置数量。

非阻塞网络 I/O 能让少量 worker 管理大量连接。磁盘访问、复杂计算或阻塞模块仍会拖慢事件循环。文件 I/O 可按平台和配置使用异步机制或线程池。

Apache 的 prefork、worker 与 event MPM 有不同模型。比较性能应说明使用的 MPM、模块与工作负载。

下面片段放在 http 上下文中。

upstream backend {
least_conn;
server 10.0.0.11:8080 weight=2 max_fails=3 fail_timeout=10s;
server 10.0.0.12:8080 max_fails=3 fail_timeout=10s;
keepalive 64;
}
server {
listen 8080;
server_name example.com;

location /static/ {
root /data/www;
expires 7d;
}
location /api/ {
proxy_pass http://backend;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_connect_timeout 3s;
proxy_read_timeout 30s;
}
}

/static/a.css 映射到 /data/www/static/a.css。上游接收到的请求仍带 /api/ 前缀。HTTP/1.1 与清空 Connection 配合上游连接复用。

Nginx 1.29.7 前默认代理 HTTP/1.0。1.29.7 起默认是 HTTP/1.1。显式配置便于跨版本说明意图。

nginx -t 检查配置语法及引用文件。通过后可用 nginx -s reload 重载。master 成功应用新配置后,启动新 worker。旧 worker 完成已有请求后退出。

2.1 连接容量​

worker_connections 约束每个 worker 的连接数。客户端和上游连接都占用额度。HTTP 反向代理的一次活跃请求可占两侧连接。

文件描述符上限也约束实际容量。因此,worker 数量乘连接额度只给出粗略上界。HTTP/2 多路复用和上游复用还会改变比例。

keepalive 64 表示每个 worker 缓存最多 64 条空闲连接。活跃上游连接可超出该值。上游并发控制需另行配置和评估。

3. 负载均衡​

算法配置适用条件
加权轮询weight按后端能力分配请求
最少连接least_conn请求占用时间差异较大
IP 哈希ip_hash需要按地址粘滞,注意 NAT 聚集
一致性哈希hash $request_uri consistent缓存按键分布

被动健康检查记录上游失败。max_fails=3 fail_timeout=10s 表示窗口内达到三次失败。后端随后在指定时段内被视为不可用。失败类型受 proxy_next_upstream 等配置影响。只有一个后端时,max_fails 与 fail_timeout 会被忽略。

四层关注连接与地址端口,七层解析应用协议。Nginx stream 也能提供四层代理。四层全代理会拆成两条连接,LVS NAT、DR 则转发原连接。具体性能需结合实现、TLS 和请求负载测试。

LVS 模式请求与响应路径
NAT改写目的地址;响应也经调度器反向转换
DR修改目的 MAC;后端直接响应客户端
TUN封装转发;后端解封装后直接响应

DR 要求调度器和后端处于可直达的二层网络。后端配置 VIP,并约束 VIP 的 ARP 应答。TUN 依赖隧道和底层可达性。绕过响应流量可减轻调度器带宽压力。

FULLNAT 属于特定 LVS 扩展实现,例如阿里 LVS。它同时改写源、目的地址。TOA 等扩展可传递客户端地址,需两端配合。部署时需确认实现支持。

Keepalived 可用 VRRP 协调 VIP 主备切换。健康检查还可维护 LVS 后端列表。接管 VIP 后,业务恢复仍依赖容量和连接状态。

4. 502 与 504​

状态解释与线索
500当前响应方内部错误,可由应用或代理产生
502上游连接失败、无有效响应或无可用后端
503服务不可用;Nginx limit_req 默认拒绝码
504网关等待上游超时
499Nginx 日志记录客户端提前关闭

上游返回的状态码也可被代理直接传递。应结合 upstream_status、错误日志与应用日志定位。无可用上游的 no live upstreams 对应 502。

  1. 查看 error.log,确认连接、响应头或读取阶段。
  2. 对比 upstream_addr、upstream_status 与各阶段耗时。
  3. 核对异常后端的监听、负载、线程池和依赖。
  4. 检查超时、连接复用及重试配置。
  5. 用用户请求成功率与延迟验证修复。

Connection refused 表示连接遭到明确拒绝。进程未监听是原因之一,策略拒绝也需核对。upstream timed out 则需结合日志中的阶段定位。

5. 代理超时与重试​

proxy_connect_timeout 控制上游建连等待。proxy_send_timeout 控制相邻写操作间的等待。proxy_read_timeout 控制相邻读操作间的等待。持续返回数据的响应可超过该读取超时值。

proxy_next_upstream 配置失败后换后端的条件。proxy_next_upstream_tries 限制重试次数。proxy_next_upstream_timeout 限制总重试窗口。响应已发给客户端后,换后端无法重新完成该响应。

已发给上游的 POST 等非幂等请求,默认不会这样重试。non_idempotent 会放宽该限制。业务重试仍需幂等键,因为超时后原请求也可能已提交。

6. 路径映射与真实地址​

在普通前缀 location 中,proxy_pass 的 URI 决定替换方式。

location /api/ {
proxy_pass http://backend/;
}

请求 /api/users 会转为上游 /users。去掉 backend 后面的斜杠,则保留 /api/users。正则 location 和带变量配置有额外规则。

root 将 URI 拼到根目录后。alias 将匹配的位置替换为指定路径。静态文件排查应根据最终映射检查路径权限。

X-Forwarded-For 可携带代理链地址,客户端也能伪造该头。real_ip 模块需用 set_real_ip_from 指定可信代理。源地址用于限流或审计前,必须明确可信入口。

7. 请求限流​

limit_req_zone $binary_remote_addr zone=perip:10m rate=10r/s;
server {
listen 8081;
location / {
limit_req zone=perip burst=20 nodelay;
limit_req_status 429;
proxy_pass http://backend;
}
}

此片段也放在 http 上下文中。limit_req 按泄漏桶方法控制请求速率。burst 提供超额请求额度。nodelay 允许额度内的突发立即处理。超过额度时拒绝,示例返回 429。

limit_conn 约束并发连接,与请求速率是不同维度。按 IP 限流还需考虑 NAT 用户共享地址。

8 · 面试题卡片​

本页题目与参考回答

8.1 Nginx 有什么作用?它为什么能支撑很高的并发?与 Apache 有什么区别?​

考察重点

  • master/worker 进程模型与 epoll 事件驱动。
  • 常用功能与动静分离;与 Apache 连接模型的差异。

相关内容:Nginx 的结构与常用配置、I/O 多路复用。

参考回答

Nginx 用事件循环和非阻塞网络 I/O 管理大量连接。

master 管理 worker,worker 处理就绪事件。Linux 可使用 epoll。阻塞模块和重计算仍会影响同一 worker 的请求。

它可做反向代理、静态服务、TLS、缓存与限流。配置重载时启动新 worker,旧 worker 逐步退出。容量还受连接数、文件描述符和上游能力约束。

Apache 各 MPM 的连接处理模型不同。比较时应明确 prefork、worker 或 event。工作负载与模块配置比产品名称更能解释差异。

8.2 四层负载均衡和七层负载均衡有什么区别?Nginx 和 LVS 怎样选择?LVS 有哪几种模式?​

考察重点

  • 四层与七层的依据、能力和性能差异;Nginx 的负载均衡算法。
  • LVS 各模式的报文路径与限制;Keepalived 的 VRRP。

相关内容:负载均衡、网络模型。

参考回答

四层按连接分发,七层可按应用内容路由。

LVS 在内核中转发,Nginx HTTP 代理解析请求。Nginx stream 也能承担四层代理。

LVS NAT 的响应经过调度器。DR 改目的 MAC,后端直接响应。TUN 封装请求,后端解封装并直接响应。FULLNAT 是特定扩展,实现需单独确认。

Nginx 支持加权轮询、最少连接和哈希。Keepalived 用 VRRP 协调 VIP,并可检查后端。选择方案时应考虑路由能力、容量与运维复杂度。

8.3 Nginx 返回 502 和 504 分别是什么原因?怎样排查?和 500 有什么区别?​

考察重点

  • 状态码由谁产生;502 与 504 的典型原因。
  • 从 Nginx 错误日志和上游字段定位到具体后端;长连接复用导致的 502。

相关内容:502 与 504、Linux 网络排查。

参考回答

502 表示上游通信异常,504 表示网关等待上游超时。

500 表示响应方内部错误,应用和代理都可产生。状态码也可能由上游透传。

先看 error.log 的错误阶段。再结合 upstream_addr、upstream_status 和耗时定位后端。检查监听、负载、池等待及依赖。复用连接被对端关闭时,应核对双方空闲超时。

proxy_read_timeout 限制相邻读取的等待。超时处理需结合业务期限和重试副作用。无可用上游会产生 502,应检查被动健康状态。

8.4 worker_connections 与 keepalive 能直接算出业务并发上限吗?​

考察重点:双侧连接、文件描述符与空闲缓存。

相关内容:连接容量。

参考回答

worker_connections 包含客户端和上游连接。

实际容量还受文件描述符及业务处理能力约束。keepalive 只限制每个 worker 的上游空闲缓存。活跃连接可超过该数量,需独立评估上游并发。

8.5 proxy_read_timeout=30s 会限制总响应时间吗?POST 超时能否换后端重试?​

考察重点:相邻读超时、重试窗口与幂等性。

相关内容:代理超时与重试。

参考回答

它限制相邻两次读取间的等待。

持续返回数据时,总响应可超过 30 秒。已发送的非幂等请求默认不会换后端重试。non_idempotent 可放宽限制,但需业务幂等保护。次数和时间窗口也应通过重试参数限制。

8.6 proxy_pass 末尾斜杠有什么影响?怎样可信地取得客户端地址?​

考察重点:URI 替换规则与可信代理。

相关内容:路径映射与真实地址。

参考回答

普通前缀 location 中,proxy_pass 是否带 URI 决定是否替换匹配前缀;客户端地址则只能从可信代理提供的信息中取得。

例如 location /api/ 配合 proxy_pass http://backend/ 时,/api/users 转为 /users;改成不带 URI 的 proxy_pass http://backend 时保留原路径。

客户端可伪造 X-Forwarded-For。配置 real_ip 时,只信任 set_real_ip_from 指定的代理。

8.7 limit_req 的 burst 与 nodelay 分别做什么?​

考察重点:平均速率、突发额度与拒绝行为。

相关内容:请求限流。

参考回答

burst 允许一定数量的超额请求。

默认会按配置速率延迟处理。nodelay 让额度内突发立即通过。超过额度仍会拒绝。limit_req_status 可将拒绝码设为 429。并发连接上限由 limit_conn 等机制另行控制。

9. 参考资料​