Caddy 从入门到精通 / 04 - 反向代理 / Reverse Proxy
反向代理 / Reverse Proxy
反向代理是 Caddy 最常用的功能之一。它将客户端请求转发到后端服务,并将响应返回给客户端。
A reverse proxy forwards client requests to backend servers and returns their responses. It is one of Caddy’s most commonly used features.
🟢 基础 / Basics
最简反向代理
example.com {
reverse_proxy localhost:3000
}
所有 example.com 的请求都会被转发到 localhost:3000。Caddy 同时自动配置 HTTPS。
代理到 Unix Socket
example.com {
reverse_proxy unix//run/app.sock
}
后端是 Gunicorn、uvicorn 等通过 Unix Socket 通信时非常常见。
代理到多个后端(简单负载均衡)
example.com {
reverse_proxy localhost:3000 localhost:3001 localhost:3002
}
默认使用 round_robin 策略轮询。
🟡 进阶 / Intermediate
负载均衡策略
example.com {
reverse_proxy localhost:3000 localhost:3001 localhost:3002 {
lb_policy round_robin
}
}
可用策略:
| 策略 | 说明 |
|---|---|
first | 选第一个可用的 |
round_robin | 轮询(默认) |
least_conn | 最少连接 |
ip_hash | 按客户端 IP 哈希,保证同一客户端访问同一后端 |
cookie | 按 cookie 哈希(会话保持) |
uri_hash | 按请求 URI 哈希 |
header | 按指定 header 哈希 |
健康检查
example.com {
reverse_proxy localhost:3000 localhost:3001 {
lb_policy round_robin
health_path /healthz
health_interval 10s
health_timeout 5s
}
}
Caddy 会定期请求后端的 /healthz,不健康的后端会被暂时移除。
修改请求头
example.com {
reverse_proxy localhost:3000 {
header_up Host {upstream_hostport}
header_up X-Real-IP {remote_host}
header_up X-Forwarded-For {remote_host}
header_up X-Forwarded-Proto {scheme}
}
}
header_up 修改发送给上游的请求头。
header_down 修改返回给客户端的响应头:
reverse_proxy localhost:3000 {
header_down -Server
header_down -X-Powered-By
}
路径匹配代理
只代理特定路径:
example.com {
# /api/* 转发到后端
handle /api/* {
reverse_proxy localhost:8080
}
# 其他路径静态文件
handle {
root * /var/www/html
file_server
}
}
路径重写 + 代理
example.com {
handle /api/* {
uri strip_prefix /api
reverse_proxy localhost:3000
}
}
客户端请求 /api/users → 后端收到 /users。
🔴 高级 / Advanced
WebSocket 代理
Caddy 自动处理 WebSocket 升级,无需额外配置:
example.com {
reverse_proxy localhost:3000
}
Caddy 检测到 Upgrade: websocket 头后自动切换到双向流转发。
如果需要显式控制:
example.com {
reverse_proxy localhost:3000 {
header_up Connection {>Connection}
header_up Upgrade {>Upgrade}
}
}
gRPC 代理
example.com {
reverse_proxy localhost:50051 {
transport http {
versions h2c
}
}
}
h2c 是明文 HTTP/2,gRPC 后端(如 Go 的 gRPC server)常用。
自定义传输配置
example.com {
reverse_proxy localhost:3000 {
transport http {
dial_timeout 5s
response_header_timeout 30s
read_buffer_size 8192
write_buffer_size 8192
max_idle_conns 100
idle_conn_timeout 60s
}
}
}
流式响应(Streaming)
Caddy 默认缓冲响应。对于 SSE(Server-Sent Events)或流式 API,需要关闭缓冲:
example.com {
reverse_proxy localhost:3000 {
flush_interval -1
}
}
flush_interval -1 表示立即 flush,不做任何缓冲。
如果需要周期性 flush(比如每 1 秒):
reverse_proxy localhost:3000 {
flush_interval 1s
}
动态上游(Dynamic Upstream)
通过 SRV DNS 记录发现后端:
example.com {
reverse_proxy {
to _api._tcp.example.com
lb_policy round_robin
}
}
Caddy 会自动查询 SRV 记录获取后端地址。
处理上游错误
example.com {
reverse_proxy localhost:3000 {
fail_duration 10s
max_fails 3
unhealthy_status 5xx
unhealthy_latency 5s
}
}
如果后端连续 3 次返回 5xx,Caddy 会将其标记为不健康,10 秒后重试。
反向代理 + 静态文件 fallback
后端挂掉时自动回退到静态维护页面:
example.com {
reverse_proxy localhost:3000 {
fail_duration 5s
max_fails 1
}
# 当 reverse_proxy 无法连接时 fallback
handle_errors {
root * /var/www/maintenance
try_files /maintenance.html =503
file_server
}
}
多后端 + 条件路由
example.com {
@api path /api/*
@static path /static/*
@ws header Connection *Upgrade*
handle @api {
reverse_proxy api-server:8080
}
handle @ws {
reverse_proxy ws-server:3000
}
handle @static {
root * /var/www/static
file_server
}
handle {
reverse_proxy web-server:3001
}
}
小结 / Summary
| 层级 | 内容 |
|---|---|
| 🟢 基础 | reverse_proxy 单后端、Unix Socket、多后端 |
| 🟡 进阶 | 负载均衡策略、健康检查、header 修改、路径代理 |
| 🔴 高级 | WebSocket/gRPC 代理、流式响应、动态上游、错误回退 |