- 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>
532 lines
12 KiB
Markdown
532 lines
12 KiB
Markdown
# 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;
|
||
}
|
||
}
|
||
}
|
||
``` |