lolly/docs/04-nginx-proxy-loadbalancing.md
xfy 9cae5ad8cf chore(init): initialize project with nginx documentation
- Add Go module initialization (go 1.26)
- Add comprehensive NGINX documentation covering:
  - Overview, installation, HTTP core module
  - Proxy/load balancing, SSL/TLS, URL rewrite
  - Compression/caching, logging/monitoring
  - Security, TCP/UDP stream, mail proxy
  - Performance tuning, Git commit guide
- Add standard Go .gitignore

Co-Authored-By: Claude <noreply@anthropic.com>
2026-04-02 11:45:53 +08:00

532 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# NGINX 反向代理与负载均衡指南
## 1. 反向代理基础
### 什么是反向代理
反向代理服务器接收客户端请求将请求转发给后端服务器获取响应后返回给客户端。NGINX 作为反向代理可以:
- 隐藏后端服务器真实地址
- 实现负载均衡
- 缓存响应内容
- SSL 终端加密
- 压缩响应内容
- 请求路由与重写
### 基础配置示例
```nginx
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://backend.example.com: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;
}
}
```
---
## 2. proxy_pass 指令详解
### 语法
`proxy_pass URL;`
URL 可以是:
- HTTP 地址:`http://backend:8080`
- HTTPS 地址:`https://backend:8443`
- Unix Socket`unix:/tmp/backend.socket`
- upstream 组:`http://backend_group`
- 变量:`http://$backend`
### URI 传递规则
**带 URI 的 proxy_pass**:请求 URI 中匹配 location 的部分会被替换。
```nginx
location /name/ {
proxy_pass http://127.0.0.1/remote/;
# /name/test -> /remote/test
}
location /api/ {
proxy_pass http://backend/v1/;
# /api/users -> /v1/users
}
```
**不带 URI 的 proxy_pass**:请求 URI 以原始形式传递。
```nginx
location /some/path/ {
proxy_pass http://127.0.0.1;
# /some/path/test -> /some/path/test
}
```
**使用变量**
```nginx
location / {
proxy_pass http://$backend;
# 需要配合 resolver 指令解析域名
}
resolver 10.0.0.1 valid=300s;
```
---
## 3. 请求头设置
### proxy_set_header
设置传递给后端服务器的请求头。
```nginx
proxy_set_header Host $host; # 传递原始 Host
proxy_set_header Host $http_host; # 传递 Host 头(含端口)
proxy_set_header Host backend.example.com; # 固定 Host 值
proxy_set_header X-Real-IP $remote_addr; # 客户端真实 IP
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # 代理链
proxy_set_header X-Forwarded-Proto $scheme; # 原始协议
# 删除请求头
proxy_set_header Accept-Encoding ""; # 删除该字段
```
### 默认行为
| 头字段 | 默认值 |
|--------|--------|
| `Host` | `$proxy_host`proxy_pass 中的地址) |
| `Connection` | `close` |
---
## 4. 负载均衡配置
### upstream 块定义
```nginx
upstream backend {
server backend1.example.com weight=5;
server backend2.example.com:8080;
server 192.168.0.1:8080 max_fails=3 fail_timeout=30s;
server backend3.example.com backup; # 备份服务器
server unix:/tmp/backend4;
}
server {
location / {
proxy_pass http://backend;
}
}
```
### 负载均衡算法
| 算法 | 指令 | 说明 |
|------|------|------|
| **轮询** | 默认 | 请求依次分发(加权) |
| **最少连接** | `least_conn;` | 分配给活动连接最少的服务器 |
| **IP Hash** | `ip_hash;` | 同一客户端 IP 始终路由到同一服务器 |
| **Hash** | `hash key [consistent];` | 基于指定键哈希,支持一致性哈希 |
| **随机** | `random [two [method]];` | 随机选择two 表示选两台再择优 |
### 配置示例
**轮询(默认)**
```nginx
upstream backend {
server srv1.example.com;
server srv2.example.com;
server srv3.example.com;
}
```
**加权轮询**
```nginx
upstream backend {
server srv1.example.com weight=5; # 5/7 的请求
server srv2.example.com weight=2; # 2/7 的请求
server srv3.example.com; # 1/7 的请求(默认 weight=1
}
```
**最少连接**
```nginx
upstream backend {
least_conn;
server srv1.example.com;
server srv2.example.com;
server srv3.example.com;
}
```
**IP Hash会话持久性**
```nginx
upstream backend {
ip_hash;
server srv1.example.com;
server srv2.example.com;
server srv3.example.com;
}
```
**一致性哈希**
```nginx
upstream backend {
hash $request_uri consistent;
server srv1.example.com;
server srv2.example.com;
server srv3.example.com;
}
```
### server 指令参数
| 参数 | 说明 | 默认值 |
|------|------|--------|
| `weight=N` | 权重值 | 1 |
| `max_conns=N` | 最大并发连接数 | 0无限制 |
| `max_fails=N` | 失败次数阈值 | 1 |
| `fail_timeout=T` | 失败统计时间及不可用持续时间 | 10s |
| `backup` | 备份服务器(主服务器不可用时使用) | - |
| `down` | 标记为永久不可用 | - |
| `resolve` | 监控域名 IP 变化(需 zone + resolver | - |
```nginx
upstream backend {
zone backend 64k;
resolver 10.0.0.1;
server backend1.example.com weight=5 max_fails=3 fail_timeout=30s;
server backend2.example.com resolve;
server backup1.example.com backup;
}
```
---
## 5. 健康检查
### 被动健康检查(内置)
```nginx
upstream backend {
server srv1.example.com max_fails=3 fail_timeout=30s;
server srv2.example.com max_fails=3 fail_timeout=30s;
}
```
**机制**
-`fail_timeout` 时间内连续失败 `max_fails` 次,服务器标记为不可用
- `fail_timeout` 时间后再次尝试
### 主动健康检查NGINX Plus
```nginx
upstream backend {
zone backend 64k;
server srv1.example.com;
server srv2.example.com;
health_check interval=5s fails=3 passes=2;
health_check uri=/health;
}
```
---
## 6. 超时配置
### 主要超时指令
| 指令 | 说明 | 默认值 |
|------|------|--------|
| `proxy_connect_timeout` | 建立连接超时 | 60s |
| `proxy_send_timeout` | 传输请求超时 | 60s |
| `proxy_read_timeout` | 读取响应超时 | 60s |
```nginx
location / {
proxy_connect_timeout 5s;
proxy_send_timeout 10s;
proxy_read_timeout 30s;
proxy_pass http://backend;
}
```
---
## 7. 缓冲配置
### 响应缓冲
```nginx
proxy_buffering on; # 默认 on
proxy_buffer_size 4k; # 响应头缓冲区大小
proxy_buffers 8 16k; # 响应体缓冲区数量和大小
proxy_busy_buffers_size 32k; # 同时发送给客户端的缓冲区总大小
proxy_max_temp_file_size 1024m; # 临时文件最大大小
proxy_temp_file_write_size 64k; # 每次写入临时文件大小
```
### 禁用缓冲(实时传输)
```nginx
location /stream/ {
proxy_buffering off;
proxy_pass http://backend;
}
```
---
## 8. 缓存配置
### 缓存路径定义
```nginx
http {
proxy_cache_path /data/nginx/cache
levels=1:2 # 目录层级1:2 表示 16*256 个子目录)
keys_zone=one:10m # 共享内存区名称和大小1MB 约 8000 个键)
inactive=60m # 非活动数据保留时间
max_size=1g # 缓存最大大小
use_temp_path=off; # 临时文件存放位置
}
```
### 启用缓存
```nginx
server {
location / {
proxy_cache one; # 使用定义的缓存区
proxy_cache_key "$host$request_uri"; # 缓存键
proxy_cache_valid 200 302 10m; # 200/302 响应缓存 10 分钟
proxy_cache_valid 404 1m; # 404 响应缓存 1 分钟
proxy_cache_valid any 1m; # 其他响应缓存 1 分钟
proxy_pass http://backend;
}
}
```
### 缓存条件控制
```nginx
# 不从缓存获取响应的条件
proxy_cache_bypass $cookie_nocache $arg_nocache;
# 不将响应保存到缓存的条件
proxy_no_cache $http_pragma $http_authorization;
```
### 使用过期缓存
```nginx
proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
# 在后端错误、超时、正在更新时使用过期缓存
```
### 缓存锁
```nginx
proxy_cache_lock on; # 同时刻只允许一个请求填充缓存
proxy_cache_lock_timeout 5s; # 锁超时时间
```
---
## 9. 故障转移
### proxy_next_upstream
定义在何种情况下将请求传递给下一台服务器。
```nginx
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
proxy_next_upstream_timeout 30s; # 限制总时间
proxy_next_upstream_tries 3; # 限制尝试次数
```
**条件类型**
| 条件 | 说明 |
|------|------|
| `error` | 与后端建立连接出错 |
| `timeout` | 连接、传输或读取超时 |
| `invalid_header` | 后端返回空或无效响应头 |
| `http_XXX` | 后端返回指定状态码 |
| `non_idempotent` | 非幂等请求POST、LOCK也进行重试 |
---
## 10. SSL/HTTPS 代理
### 代理到 HTTPS 后端
```nginx
location / {
proxy_pass https://backend.example.com;
proxy_ssl_verify on; # 验证后端证书
proxy_ssl_trusted_certificate /path/to/ca.crt;
proxy_ssl_verify_depth 2;
proxy_ssl_server_name on; # 启用 SNI
}
```
### 代理 SSL 配置
| 指令 | 说明 | 默认值 |
|------|------|--------|
| `proxy_ssl` | 启用 HTTPS 代理 | off |
| `proxy_ssl_protocols` | 启用的协议 | TLSv1.2 TLSv1.3 |
| `proxy_ssl_ciphers` | 加密套件 | DEFAULT |
| `proxy_ssl_verify` | 验证后端证书 | off |
| `proxy_ssl_verify_depth` | 验证深度 | 1 |
| `proxy_ssl_server_name` | 启用 SNI | off |
| `proxy_ssl_certificate` | 客户端证书 | - |
| `proxy_ssl_certificate_key` | 客户端密钥 | - |
---
## 11. WebSocket 代理
### 基础配置
```nginx
location /chat/ {
proxy_pass http://backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
```
### 动态处理
```nginx
http {
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
location /chat/ {
proxy_pass http://backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_read_timeout 3600s; # 增加超时时间
}
}
}
```
---
## 12. FastCGI 代理
### 基础配置
```nginx
location ~ \.php$ {
fastcgi_pass localhost:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
```
### 常用 FastCGI 指令
| 指令 | 说明 |
|------|------|
| `fastcgi_pass` | FastCGI 服务器地址 |
| `fastcgi_index` | URI 以斜杠结尾时追加的文件名 |
| `fastcgi_param` | 传递参数给 FastCGI 服务器 |
| `fastcgi_split_path_info` | 分离 SCRIPT_NAME 和 PATH_INFO |
| `fastcgi_connect_timeout` | 连接超时 |
| `fastcgi_read_timeout` | 读取超时 |
| `fastcgi_buffer_size` | 响应头缓冲区大小 |
| `fastcgi_buffers` | 响应体缓冲区 |
---
## 13. 内置变量
| 变量 | 说明 |
|------|------|
| `$proxy_host` | proxy_pass 中的服务器名称和端口 |
| `$proxy_port` | proxy_pass 中的端口 |
| `$proxy_add_x_forwarded_for` | X-Forwarded-For 头 + 客户端 IP |
---
## 14. 综合配置示例
```nginx
http {
upstream backend {
zone backend 64k;
least_conn;
server backend1.example.com weight=5 max_fails=3 fail_timeout=30s;
server backend2.example.com resolve;
server backup.example.com backup;
keepalive 32;
}
proxy_cache_path /data/nginx/cache levels=1:2 keys_zone=main:10m inactive=60m max_size=1g;
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://backend;
proxy_http_version 1.1;
proxy_set_header Connection "";
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_connect_timeout 5s;
proxy_read_timeout 30s;
proxy_cache main;
proxy_cache_key "$host$request_uri";
proxy_cache_valid 200 10m;
proxy_next_upstream error timeout http_502 http_503;
}
location /api/ {
proxy_pass http://backend;
proxy_set_header Host $host;
proxy_buffering off;
}
location /ws/ {
proxy_pass http://backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_read_timeout 3600s;
}
}
}
```