Nginx 是什么

一句话定义: Nginx 是一个高性能的 HTTP 和反向代理服务器,也是一个 IMAP/POP3/SMTP 代理服务器。

它的核心特点是事件驱动、异步非阻塞的架构。这和 Java 中传统的 Servlet 容器(如 Tomcat)每个请求对应一个线程的模型截然不同。Nginx 用极少的 worker 进程(通常等于 CPU 核心数),通过 epoll 等高效的 I/O 多路复用机制,轻松处理数万乃至百万级的并发连接,同时保持极低的 CPU 和内存消耗。

在分布式系统中,它就是南北向流量的总入口,是所有外部请求抵达你后台服务集群前必须经过的那扇大门。


着重介绍:Nginx 可以做什么

作为流量入口,Nginx 的能力远远超出把请求转发到后台这个范畴,它是一个功能强大的流量治理平台。

反向代理与负载均衡

  • 透明转发:客户端不知道后端真实服务器,Nginx 统一收口。
  • 负载均衡算法:支持轮询(Round Robin)、权重轮询、IP 哈希(ip_hash)、最少连接数(least_conn)、URL 哈希(hash $request_uri)等。解决了分布式 Session 问题(ip_hash)和热点请求缓存命中问题(url_hash)。
  • 失败重试与容错:当后端节点报错或超时,自动将请求转发到其他健康节点。

静态资源服务

  • 直接处理静态文件(HTML、CSS、JS、图片等),性能极高。
  • 可以彻底实现动静分离,让 Java 应用服务器专注于动态逻辑,极大释放其压力。

HTTP 缓存

  • 可作为边缘缓存节点,为静态资源或是不常变化的动态接口响应设置 expiresCache-Control 等,直接由 Nginx 返回 304 或缓存内容,无需请求后端。

安全防护底座

  • 访问控制:IP 黑白名单。
  • 限流熔断:基于请求速率(limit_req)或并发连接数(limit_conn)保护后端,防止恶意攻击或突发流量击垮系统。
  • SSL/TLS 终结:在入口统一处理 HTTPS 加解密,将 HTTPS 转换为内部的 HTTP,减轻后端服务的 CPU 负担和证书管理成本。
  • 基础 WAF:配合 ModSecurity 或使用 ngx_http_js_module 编写自定义规则,拦截 SQL 注入、XSS 等。

灰度发布与流量染色

  • 这是分布式演进中的关键能力。通过解析请求头中的 Cookie、Header(如 version: v2)或客户端 IP,将特定流量导向灰度集群,实现平滑的蓝绿部署金丝雀发布

WebSocket 代理

  • 只需简单配置 proxy_set_header UpgradeConnection,就能无缝代理 WebSocket 长连接,支撑消息推送、实时协作等场景。

流量镜像与复制

  • 使用 ngx_http_mirror_module 模块,可将生产流量复制一份到测试或新版本环境中,在不影响真实用户的前提下进行线上功能验证和压力测试。

API 网关核心功能

  • Nginx 结合 Lua 脚本(OpenResty),可以动态完成请求校验、JWT 鉴权、路由重写等复杂网关逻辑,性能远超 Java 网关。
  • 这是其成为 Kong、APISIX 等主流网关底层基石的原因。

如何使用:核心实战配置

Nginx 的配置清晰易读,掌握几个核心指令就能上手。

配置文件结构

一个典型的生产级配置结构如下,常用 include 来拆分管理:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# main 全局块
user nginx;
worker_processes auto; # 建议设为CPU核心数
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;

# events 块
events {
worker_connections 10240; # 单个worker最大连接数
use epoll; # Linux下高性能事件模型
}

# http 块,核心服务配置
http {
include /etc/nginx/mime.types;
access_log /var/log/nginx/access.log;

# 1. 定义后端服务器集群:upstream
upstream backend_cluster {
server 192.168.1.10:8080 weight=5 max_fails=3 fail_timeout=30s;
server 192.168.1.11:8080 weight=5;
server 192.168.1.12:8080 backup; # 热备节点
keepalive 32; # 长连接池大小
}

# 2. 限流配置
limit_req_zone $binary_remote_addr zone=mylimit:10m rate=10r/s;

# 3. 虚拟主机定义:server
server {
listen 443 ssl http2;
server_name api.yourdomain.com;

# SSL证书配置
ssl_certificate /etc/nginx/ssl/cert.pem;
ssl_certificate_key /etc/nginx/ssl/key.pem;

# 安全头设置
add_header X-Frame-Options "SAMEORIGIN";

# 日志格式,可记录响应时间、上游地址等
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "http_x_forwarded_for" '
'upstream_addr=$upstream_addr response_time=$upstream_response_time';

# ========= 路由规则定义:location =========

# (1) 动静分离:静态文件直接由Nginx返回
location /static/ {
alias /app/data/static/;
expires 30d;
add_header Cache-Control "public, immutable";
}

# (2) 动态接口反向代理到后端集群
location /api/ {
# 限定请求速率,超出则返回503
limit_req zone=mylimit burst=20 nodelay;

# 核心代理设置
proxy_pass http://backend_cluster;
proxy_http_version 1.1;

# 必设的请求头,向后端传递真实客户端信息
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;

# 超时设置,防止慢请求拖垮Nginx
proxy_connect_timeout 3s;
proxy_send_timeout 30s;
proxy_read_timeout 30s;

# 开启WebSocket支持
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}

# (3) 基于Header的灰度发布
location /api/ {
if ($http_x_canary = "v2") {
proxy_pass http://canary_backend_cluster;
break;
}
proxy_pass http://backend_cluster;
}
}
}

常用运维命令

1
2
3
4
5
6
7
8
9
10
11
# 启动
nginx

# 测试配置文件语法,这是修改后的第一步
nginx -t

# 在不停止服务的情况下重新加载配置
nginx -s reload

# 优雅停止(处理完当前请求)
nginx -s quit

潜在风险与注意事项

这部分是你需要特别警惕的,能避免很多线上事故。

风险与陷阱 说明与规避策略
1. proxy_pass 斜杠之坑 绝对致命location /api/proxy_pass http://backend/ (带斜杠) 会剥离 /api;若 proxy_pass 不带斜杠,则会将 /api/ 原样传给后端。路径拼接错误会导致 404。务必理解并严格测试
2. 单点故障 Nginx 自身挂掉则全站不可用。必须通过 Keepalived + 虚拟IP 或云厂商的负载均衡器搭建 Nginx 集群实现高可用。
3. 后端健康检查的局限性 开源版 Nginx 只做被动健康检查(请求失败才标记),可能已在故障节点积累不少用户报错。商业版 Nginx Plusnginx_upstream_check_module 等第三方模块支持主动探测,需权衡。
4. 超时配置不当 proxy_read_timeout 设置过长,会导致大量 worker 连接被慢请求或故障后端耗尽,引发雪崩。需根据你最慢的接口设置合理的超时时间。
5. 文件描述符限制 Linux 系统对单进程可打开文件数有限制(默认1024)。高并发下,必须将 worker 的 worker_rlimit_nofile 和系统 ulimit -n 调到 65535 或更高。
6. 动态服务发现集成难 Nginx 的 upstream 里写死 IP 或域名。在容器化(K8s)环境中,Pod 不断变化,IP 写死不可行。虽然可以用 DNS 解析,但 Nginx 在启动时就会缓存 DNS 结果。解决方案是:使用 resolve 指令配合变量,或采用 OpenResty + Lua 从注册中心动态获取,或干脆在 K8s 前端再套一层 Ingress Controller。
7. 日志磁盘打满 默认的 access.log 增长极快。务必配置日志切割(如 logrotate),并只记录必要信息。
8. 内存消耗与性能陷阱 配置错误如 ip_hash 时后端增减节点会导致哈希重映射,大量用户 Session 失效。limit_req 基于共享内存,设置过小会导致限流不准。

有哪些替代方案

Nginx 并非银弹,在不同维度下,这些优秀的替代品值得你了解。

替代方案 核心理念与对比 适用场景
1. HAProxy 纯血负载均衡器,四层(TCP)代理性能极强,七层(HTTP)现在也很强。配置语法更像 DSL,精细的会话保持和健康检查是其强项。 追求极致负载均衡能力和稳定性,不强制要求 Web Server 功能的场景。常与 Nginx 搭配(L4用HAProxy, L7用Nginx)。
2. Envoy 云原生新一代代理,为服务网格而生。通过 xDS 协议动态发现配置,无需重启。内置丰富的可观测性(Prometheus 指标、分布式追踪)。 容器化、Kubernetes 环境,尤其是 Istio 服务网格的数据面。对 Java 开发者来说,与之集成的门槛稍高,但前景广阔。
3. Traefik 针对微服务/容器设计,能自动监听 Docker/K8s 事件并动态生成路由规则,自动签发和续期 Let’s Encrypt 证书。 K8s Ingress 场景,希望零配置自动发现服务。
4. API 网关类(Kong, APISIX) 这些网关底层就是 OpenResty(Nginx + Lua)。它们加上了可视化管理界面、丰富的插件市场(鉴权、限流、监控)、动态配置热加载能力。 需要将 Nginx 作为统一 API 网关来管理,并且团队希望有 UI、插件生态和动态配置,而不是手写配置文件。
5. 硬件负载均衡 (F5, A10) 专用硬件设备,性能最强,功能最全,价格也最昂贵。 金融、运营商等对吞吐量、稳定性、安全有极致要求的核心系统。
6. Java 栈方案 (Spring Cloud Gateway, Zuul) 纯 Java 编写的网关,对 Java 团队最友好,可直接集成微服务生态中的注册中心(Nacos/Eureka)、配置中心、Sentinel 熔断。但每请求一线程模型下,性能和资源消耗与 Nginx 有数量级差距 作为微服务聚合层的二级网关,负责鉴权、协议转换等复杂业务逻辑,而 Nginx 作为总入口一级网关,抗下最前端流量。这是典型的组合拳。
7. Caddy 用 Go 语言编写,以简单和安全著称。最大的亮点是自动 HTTPS,它默认就会自动为你申请和续期 SSL 证书。配置极其简洁。 中小项目或个人开发者,希望在极简配置下实现现代化 Web Server 功能。

总结

对 Java 开发者而言,Nginx 不仅是部署时需要配置一下的工具,更是理解整个分布式流量治理体系的起点。

  • 它是门面,更是高性能守护者:用 C 语言的极致性能,在最前沿解决掉海量并发、静态资源和安全防护的共性问题,让你后端精心设计的 Java 微服务能纯粹地服务业务。
  • 掌握配置是基础,理解模型是关键:事件驱动模型、upstream 健康检查机制、请求处理阶段(11 个阶段)是深入排查问题和优化的基础。
  • 最佳实践是组合:架构上,经典分层是 DNS -> 云LB/硬件LB -> Nginx(L4/L7) -> API网关(Java/Golang) -> 微服务。Nginx 负责高效转发、安全、限流;网关负责鉴权、协议转换、聚合等复杂业务逻辑。
  • 演进方向是动态化:面对频繁变动的云原生环境,静态配置文件的劣势凸显。后续你可以进一步研究 OpenResty,用 Lua 脚本来动态控制流量;或直接关注 Kong/APISIX 这类Nginx 的完全体网关,它们在保留内核的同时,提供了动态化、可视化和丰富插件生态的现代化体验。