1 nginx 介绍
Nginx(Engine X)是一款高性能的 HTTP/反向代理服务器及邮件(IMAP/POP3)代理服务器,采用事件驱动、异步非阻塞的架构,内存占用少、并发处理能力强。适合作为静态文件服务器、反向代理、负载均衡器与 API 网关的边缘组件。
补充要点:
- 常见部署形式:单机 + 负载均衡(前置 LB),或作为集群的边缘入口(搭配 Keepalived/HAProxy)实现高可用。
- 模块化:核心 + 可选模块(如
http_gzip_module
、http_stub_status_module
、http_v2_module
等),开源版与商业版(Nginx Plus)功能略有差异(例如主动健康检查、内置 Dashboard 等)。 - 常见性能指标:
worker_processes
、worker_connections
、keepalive_timeout
、sendfile
、tcp_nopush
、tcp_nodelay
等。
参考文章------Nginx详解(一文带你搞懂Nginx)
2 反向代理
2.1 正向代理和反向代理

-
正向代理:客户端知道代理,客户端把请求发给代理,由代理代表客户端去请求目标服务器。常用于客户端侧的访问控制、缓存、突破地域限制或匿名上网。
- 绕过地域限制(翻墙/访问被封锁的站点)
- 企业或学校的上网审计、过滤、访问控制与缓存(节省带宽)
- 客户端隐私/匿名(隐藏真实 IP)
- 客户端调试(通过代理抓包、修改请求)
-
反向代理:客户端不知道代理,客户端把请求发给看起来像目标服务器(或目标域名)的代理,代理再把请求转发给一个或多个后端服务。常用于负载均衡、SSL 终端、请求路由、缓存、WAF 等。
- 负载均衡(把流量分发到多台后端)
- SSL/TLS 终止(在代理处解密,后端使用 HTTP)
- 服务聚合、URL 路由、API 网关功能(认证、限流、熔断)
- 缓存静态或部分动态内容、减轻后端压力
- 安全防护(WAF、IP 限制、隐藏真实后端拓扑)
特性 | 正向代理(Forward) | 反向代理(Reverse) |
---|---|---|
谁主动配置代理? | 客户端(浏览器/系统) | 服务端(DNS 指向/负载均衡) |
目标服务器看到的 IP | 看到代理 IP(不是客户端) | 看到的是反向代理 IP(后端看不到真实客户端,除非代理透传) |
常见用途 | 绕过限制、缓存、审计、匿名 | 负载均衡、SSL 终止、缓存、路由、WAF |
典型软件 | Squid、Shadowsocks、V2Ray、SSH -D | Nginx、HAProxy、Cloudflare、Kong |
是否对外公开后端拓扑? | 不改变目标服务器拓扑 | 隐藏后端拓扑(对外只暴露代理) |
2.2 配置案例
2.2.1 示例1 最简单的反向代理(单一后端)
nginx
# 说明:对外暴露 80,将所有 /api/ 请求转发到后端服务(带路径替换)
server {
listen 80;
server_name example.com;
# 限制上传大小(常用于文件上传服务)
client_max_body_size 50m;
location /api/ {
# 转发到后端(末尾带 / 表示替换前缀)
proxy_pass http://10.0.0.10:8080/;
# 常用代理头,保留客户端真实 IP 等
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_connect_timeout 5s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
# WebSocket 支持(若后端需要)
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
}
注解:
proxy_pass
末尾的/
决定是否保留 location 的匹配前缀。
2.2.2 示例2 反向代理 + 静态与应用分离
nginx
# 说明:/static/ 由 Nginx 直接提供,/ 替代理到应用服务器
server {
listen 80;
server_name app.example.com;
root /var/www/app; # 存放静态文件的本地路径
index index.html;
# 静态资源优先
location /static/ {
alias /var/www/app/static/; # alias 与 root 的区别:alias 用于替换 location
expires 30d; # 浏览器缓存时间
add_header Cache-Control "public";
try_files $uri $uri/ =404;
}
# 其余请求代理到应用
location / {
proxy_pass http://127.0.0.1:3000;
include proxy_params; # 推荐把公共 header 放在单独文件中
}
}
在 Nginx 配置中,root
和 index
指令共同决定了静态文件的处理逻辑。以下是具体作用和示例说明:
root
** 指令**
作用 :设置请求的根目录路径。当 Nginx 处理请求时,会将 URL 路径拼接到 root
指定的路径后,形成完整的本地文件路径。
示例:
- 请求:
http://app.example.com/images/logo.png
Nginx 会查找文件:/var/www/app/images/logo.png
(root
路径/var/www/app
+ URL 路径/images/logo.png
) - 请求:
http://app.example.com/about/index.html
Nginx 会查找文件:/var/www/app/about/index.html
index
** 指令**
作用:定义当请求指向目录(而非具体文件)时,默认返回的文件名列表。Nginx 会按顺序检查列表中的文件是否存在,返回第一个匹配的文件。
示例:
- 请求:
http://app.example.com/
(指向根目录)
Nginx 会尝试按顺序查找:
/var/www/app/index.html
→ 若存在则返回该文件;
若不存在,则继续执行location /
的代理规则(转发到后端应用)。 - 请求:
http://app.example.com/docs/
(指向目录)
Nginx 会尝试查找:
/var/www/app/docs/index.html
→ 返回该文件(如果存在)。
关键注意事项
- 静态文件优先级 :
location /static/
优先于location /
。- 请求
http://app.example.com/static/style.css
→ 由 Nginx 直接返回文件(不代理到后端)。 - 请求
http://app.example.com/api/data
→ 代理到后端应用服务器(http://127.0.0.1:3000/api/data
)。
- 请求
- 目录请求的处理流程 :
- 若请求以
/
结尾(如http://app.example.com/
),Nginx 会尝试返回index
指定的文件(如index.html
)。 - 若
index
文件不存在,请求会落入location /
被代理到后端(由后端应用处理)。
- 若请求以
alias
** vs **root
:location /static/
使用alias
:URL 中的/static/
会被替换为/var/www/app/static/
。
示例:请求/static/logo.png
→ 实际文件路径为/var/www/app/static/logo.png
。- 若此处改用
root
,路径会变为/var/www/app/static/logo.png
(多一层/static
)。
总结
root
:定义静态文件的根目录基础路径。index
:指定目录请求的默认返回文件。- 协作效果:两者结合确保 Nginx 能高效处理静态资源(如 HTML、CSS、图片),并将动态请求无缝转发到后端应用。
2.2.3 示例3 反向代理 + 按路径分发到不同后端(微服务网关场景)
nginx
# 说明:把不同 API 路径路由到不同后端服务
upstream auth_service {
server 10.0.0.11:8081;
server 10.0.0.12:8081;
}
upstream user_service {
server 10.0.0.21:8080;
}
server {
listen 80;
server_name api.example.com;
location /auth/ {
proxy_pass http://auth_service/; # 注意末尾 /
include proxy_params;
}
location /user/ {
proxy_pass http://user_service/;
include proxy_params;
}
}
2.2.4 示例4 支持 HTTPS 的反向代理(SSL 终止)
nginx
server {
listen 443 ssl http2;
server_name secure.example.com;
ssl_certificate /etc/ssl/certs/example.crt;
ssl_certificate_key /etc/ssl/private/example.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
location / {
# SSL 在这里终止,后端可以使用 HTTP
proxy_pass http://127.0.0.1:8080;
include proxy_params;
}
}
注:生产环境建议开启强安全配置(OCSP stapling、HSTS、现代 TLS 配置),在生产完整配置中会给出建议项。
2.2.5 案例5 基本的HTTP反向代理
将访问 <font style="color:rgb(15, 17, 21);background-color:rgb(235, 238, 242);">nginx-proxy.com</font>
的请求代理到运行在 <font style="color:rgb(15, 17, 21);background-color:rgb(235, 238, 242);">http://localhost:8080</font>
的后端Java应用。
nginx
http {
server {
listen 80; # 监听80端口
server_name nginx-proxy.com; # 指定域名
location / {
# 核心代理指令,将请求转发到 upstream 或指定地址
proxy_pass http://localhost:8080;
# 以下是一些常用的代理头设置,用于向后端传递客户端信息
proxy_set_header Host $host; # 将原始请求的Host头传递给后端
proxy_set_header X-Real-IP $remote_addr; # 传递客户端的真实IP
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # 追加客户端IP到XFF头
proxy_set_header X-Forwarded-Proto $scheme; # 传递客户端使用的协议(http/https)
# 连接超时、发送超时、读取超时时间(单位:秒)
proxy_connect_timeout 30;
proxy_send_timeout 30;
proxy_read_timeout 60;
}
}
}
2.2.6 案例6 根据路径反向代理到不同服务
- 将
<font style="color:rgb(15, 17, 21);background-color:rgb(235, 238, 242);">/api/</font>
开头的请求代理到后端API服务器 (<font style="color:rgb(15, 17, 21);background-color:rgb(235, 238, 242);">http://api-backend:3000</font>
)。 - 其他所有请求代理到前端静态服务器 (
<font style="color:rgb(15, 17, 21);background-color:rgb(235, 238, 242);">http://frontend:80</font>
)。
nginx
http {
server {
listen 80;
server_name my-app.com;
# 代理 /api/ 路径到后端API服务
location /api/ {
proxy_pass http://api-backend:3000/; # 注意结尾的 /,它会将 /api/xxx 转换为 /xxx 传递给后端
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
# 代理所有其他请求到前端服务
location / {
proxy_pass http://frontend:80;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
}
3 负载均衡
3.1 负载均衡 介绍
负载均衡建立在现有网络结构之上,它提供了一种廉价有效透明的方法扩展网络设备和服务器的带宽、增加吞吐量、加强网络数据处理能力、提高网络的灵活性和可用性。其意思就是分摊到多个操作单元上进行执行,例如Web服务器、FTP服务器、企业关键应用服务器和其它关键任务服务器等,从而共同完成工作任务。
简单来说就是:现有的请求使服务器压力太大无法承受,所有我们需要搭建一个服务器集群,去分担原先一个服务器所承受的压力。Nginx提供了多种负载均衡算法:
- 轮询 (Round Robin): 默认方法。每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器宕机,能自动剔除。
- 加权轮询 (Weighted Round Robin) : 指定轮询几率,
<font style="color:rgb(15, 17, 21);background-color:rgb(235, 238, 242);">weight</font>
(权重)和访问比率成正比。用于后端服务器性能不均的情况。权重越高,被分配到的概率越大。 - IP哈希 (ip_hash): 每个请求按访问IP的hash结果分配。这样每个访客固定访问一个后端服务器,可以解决Session共享的问题(但非最佳方案,通常建议使用共享Session存储)。
上述方式存在一个问题就是说,在负载均衡系统中,假如用户在某台服务器上登录了,那么该用户第二次请求的时候,因为我们是负载均衡系统,每次请求都会重新定位到服务器集群中的某一个,那么已经登录某一个服务器的用户再重新定位到另一个服务器,其登录信息将会丢失,这样显然是不妥的。
我们可以采用ip_hash指令解决这个问题,如果客户已经访问了某个服务器,当用户再次访问时,会将该请求通过哈希算法,自动定位到该服务器。每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务器,可以解决session的问题。
- 最少连接 (least_conn): 优先将请求分配给当前连接数最少的后端服务器。
3.2 配置案例
3.2.1 案例1 最简单的轮询(默认)
nginx
upstream backend_rr {
server 10.0.0.11:8080;
server 10.0.0.12:8080;
}
server {
listen 80;
server_name lb.example.com;
location / {
proxy_pass http://backend_rr;
include proxy_params;
}
}
3.2.2 案例2 加权轮询(weight)
nginx
upstream backend_weight {
server 10.0.0.11:8080 weight=3; # 更强的服务器,3 倍权重
server 10.0.0.12:8080 weight=1;
}
# 使用方式与上文相同
3.2.3 案例3 ip_hash(会话亲和)
nginx
upstream backend_iphash {
ip_hash; # 依据客户端 IP 哈希选择后端
server 10.0.0.11:8080;
server 10.0.0.12:8080;
}
注意:
ip_hash
与weight
不能同时使用;并且当后端池发生变更(添加/删除节点)时,会话亲和性会打破。
3.2.4 案例4 least_conn(最少连接)
nginx
upstream backend_leastconn {
least_conn;
server 10.0.0.11:8080;
server 10.0.0.12:8080;
}
3.2.5 案例5 keepalive 与被动健康检查
nginx
upstream backend_keepalive {
server 10.0.0.11:8080 max_fails=3 fail_timeout=30s; # 被动剔除(3 次失败,30s 内视为 down)
server 10.0.0.12:8080 max_fails=3 fail_timeout=30s;
keepalive 32; # 与后端保持 32 个空闲连接复用
}
server {
listen 80;
location / {
proxy_pass http://backend_keepalive;
proxy_http_version 1.1;
proxy_set_header Connection ""; # 允许复用 keepalive
include proxy_params;
}
}
说明:被动健康检查靠
max_fails
+fail_timeout
。如需主动健康检查,推荐:Nginx Plus、nginx_upstream_check_module 或外部探活(例如 Kubernetes readiness probe 或 Keepalived + 脚本)。
4.1 动静分离介绍
Nginx的静态资源处理能力非常高效(得益于高效的异步非阻塞事件处理模型和<font style="color:rgb(15, 17, 21);background-color:rgb(235, 238, 242);">sendfile</font>
等系统调用),而动态内容处理(如PHP、Python程序)通常由专门的应用服务器(如Tomcat, uWSGI, PHP-FPM)负责。动静分离技术通过代理的方式,在<font style="color:rgb(15, 17, 21);background-color:rgb(235, 238, 242);">server{}</font>
配置段中使用带正则匹配的<font style="color:rgb(15, 17, 21);background-color:rgb(235, 238, 242);">location</font>
指令,将静态资源(如图片、JS、CSS、HTML)的请求直接由Nginx本地处理,而动态请求则代理给后端的应用服务器处理。这样做可以:
- 减轻应用服务器的负载,让其专注于处理动态请求。
- 充分利用Nginx的高效特性来快速响应静态资源请求。
- 可以方便地对静态资源进行缓存优化。

4.2 配置案例
4.2.1 案例1 经典的动静分离配置
假设静态文件存放在 <font style="color:rgb(15, 17, 21);background-color:rgb(235, 238, 242);">/data/www/static</font>
,动态请求需要代理到 <font style="color:rgb(15, 17, 21);background-color:rgb(235, 238, 242);">http://tomcat-app:8080</font>
。
nginx
http {
server {
listen 80;
server_name www.example.com;
root /data/www; # 设置服务器默认根目录
# location ~* \.(gif|jpg|jpeg|png|css|js|ico|html)$ 是更常见的匹配静态文件的正则写法
# 处理静态资源请求 (图片、样式、脚本等)
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf|css|js|flv|ico)$ {
# 指定静态文件的实际存放路径
root /data/www/static;
# 启用高效文件传输 sendfile
sendfile on;
# 防止某些系统安全限制问题
sendfile_max_chunk 1m;
# 设置浏览器缓存过期时间,减少重复请求
expires 30d; # 缓存30天
# 尝试直接返回文件,如果没找到则继续寻找其他location或返回404
try_files $uri $uri/ =404;
}
# 处理所有动态请求,代理到Tomcat
location / {
proxy_pass http://tomcat-app:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
}
4.2.2 案例2 更清晰的路径分
将静态路径 <font style="color:rgb(15, 17, 21);background-color:rgb(235, 238, 242);">/static/</font>
和动态路径 <font style="color:rgb(15, 17, 21);background-color:rgb(235, 238, 242);">/api/</font>
明确分开。
nginx
http {
server {
listen 80;
server_name api-static-site.com;
root /usr/share/nginx/html;
# 所有 /static/ 路径下的请求被认为是静态资源
location /static/ {
# 静态文件目录,alias 路径末尾必须加 /
alias /usr/share/nginx/html/static/;
# 启用sendfile
sendfile on;
# 设置缓存
expires max;
# 关闭日志记录静态资源请求以提升性能(可选)
access_log off;
}
# 所有 /api/ 路径下的请求被认为是动态API
location /api/ {
proxy_pass http://api-backend:8000/; # 注意末尾的 /,它会去除 /api 前缀
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
# 处理根路径和其他未匹配的请求,可以返回首页或代理到前端应用
location / {
try_files $uri $uri/ /index.html; # 常用于单页面应用(SPA)
# 或者代理到一个前端服务器
# proxy_pass http://frontend-server:3000;
}
}
}
4.2.3 案例3 静态资源缓存 + gzip
nginx
http {
gzip on;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
gzip_min_length 1000;
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:10m max_size=10g inactive=60m use_temp_path=off;
server {
listen 80;
server_name cdn.example.com;
location / {
proxy_pass http://origin_server;
proxy_cache my_cache;
proxy_cache_valid 200 302 10m;
proxy_cache_valid 404 1m;
add_header X-Cache-Status $upstream_cache_status;
}
}
}