4.1 反向代理概述
4.1.1 什么是反向代理
反向代理是一种代理服务器,它代表服务器接收客户端的请求,然后将请求转发给后端服务器,并将后端服务器的响应返回给客户端。与正向代理不同,反向代理对客户端是透明的。
4.1.2 反向代理的优势
- 负载均衡:将请求分发到多个后端服务器
- SSL终止:在代理层处理SSL/TLS加密
- 缓存:缓存后端响应,提高性能
- 压缩:压缩响应内容,减少带宽使用
- 安全性:隐藏后端服务器的真实信息
- 高可用性:提供故障转移和健康检查
- 统一入口:为多个服务提供统一的访问入口
4.1.3 Caddy反向代理的特点
- 零配置负载均衡:自动健康检查和故障转移
- 多种负载均衡算法:支持轮询、最少连接、IP哈希等
- HTTP/2和HTTP/3支持:现代协议支持
- WebSocket支持:透明的WebSocket代理
- 自动重试:智能的请求重试机制
- 流式传输:支持大文件和流媒体代理
4.2 基础反向代理配置
4.2.1 简单反向代理
# 最简单的反向代理
example.com {
reverse_proxy localhost:8080
}
# 代理到外部服务
api.example.com {
reverse_proxy https://api.backend.com
}
# 代理特定路径
example.com {
reverse_proxy /api/* localhost:8080
file_server
}
4.2.2 多后端代理
# 多个后端服务器
example.com {
reverse_proxy localhost:8080 localhost:8081 localhost:8082
}
# 带权重的后端
example.com {
reverse_proxy localhost:8080 localhost:8081 {
# 8080端口处理更多请求
to localhost:8080 weight 3
to localhost:8081 weight 1
}
}
4.2.3 健康检查配置
example.com {
reverse_proxy localhost:8080 localhost:8081 {
# 健康检查配置
health_uri /health
health_port 8080
health_interval 30s
health_timeout 5s
health_status 200
health_body "OK"
}
}
4.3 负载均衡策略
4.3.1 轮询(Round Robin)
# 默认的轮询策略
example.com {
reverse_proxy localhost:8080 localhost:8081 localhost:8082 {
lb_policy round_robin
}
}
4.3.2 最少连接(Least Connections)
# 最少连接策略
example.com {
reverse_proxy localhost:8080 localhost:8081 localhost:8082 {
lb_policy least_conn
}
}
4.3.3 IP哈希(IP Hash)
# IP哈希策略(会话保持)
example.com {
reverse_proxy localhost:8080 localhost:8081 localhost:8082 {
lb_policy ip_hash
}
}
4.3.4 随机选择(Random)
# 随机选择策略
example.com {
reverse_proxy localhost:8080 localhost:8081 localhost:8082 {
lb_policy random
}
}
4.3.5 一致性哈希(Consistent Hash)
# 一致性哈希策略
example.com {
reverse_proxy localhost:8080 localhost:8081 localhost:8082 {
lb_policy consistent_hash {
key {http.request.header.X-User-ID}
}
}
}
4.4 高级代理配置
4.4.1 请求头处理
example.com {
reverse_proxy localhost:8080 {
# 添加请求头
header_up X-Real-IP {remote_host}
header_up X-Forwarded-For {remote_host}
header_up X-Forwarded-Proto {scheme}
header_up X-Forwarded-Host {host}
# 移除请求头
header_up -X-Sensitive-Header
# 修改请求头
header_up User-Agent "Caddy-Proxy/2.0"
}
}
4.4.2 响应头处理
example.com {
reverse_proxy localhost:8080 {
# 添加响应头
header_down X-Served-By "Caddy"
header_down X-Cache-Status "MISS"
# 移除响应头
header_down -Server
header_down -X-Powered-By
# 修改响应头
header_down Access-Control-Allow-Origin "*"
}
}
4.4.3 路径重写
example.com {
# 重写请求路径
reverse_proxy /api/v1/* localhost:8080 {
# 移除路径前缀
rewrite /api/v1/* /api/*
}
# 添加路径前缀
reverse_proxy /old-api/* localhost:8080 {
rewrite /old-api/* /v2/api/*
}
}
4.4.4 超时配置
example.com {
reverse_proxy localhost:8080 {
# 连接超时
transport http {
dial_timeout 10s
response_header_timeout 30s
expect_continue_timeout 2s
tls_handshake_timeout 10s
keep_alive 30s
keep_alive_idle_conns 10
max_idle_conns_per_host 5
}
}
}
4.5 故障处理和重试
4.5.1 重试配置
example.com {
reverse_proxy localhost:8080 localhost:8081 {
# 重试配置
fail_duration 30s
max_fails 3
unhealthy_request_count 5
# 重试条件
@retry {
status 502 503 504
}
handle_response @retry {
# 重试到其他后端
reverse_proxy localhost:8082
}
}
}
4.5.2 熔断器配置
example.com {
reverse_proxy localhost:8080 {
# 熔断器配置
circuit_breaker {
trip_duration 30s
ratio_threshold 0.5
minimum_requests 10
success_threshold 5
}
}
}
4.5.3 故障转移
example.com {
# 主后端
reverse_proxy localhost:8080 {
# 健康检查
health_uri /health
health_interval 10s
# 故障时的处理
@unhealthy {
status 502 503 504
}
}
# 备用后端
handle @unhealthy {
reverse_proxy localhost:8081
}
}
4.6 WebSocket代理
4.6.1 基本WebSocket代理
# WebSocket代理
ws.example.com {
reverse_proxy localhost:8080 {
# 自动检测WebSocket升级
# Caddy会自动处理WebSocket连接
}
}
# 特定路径的WebSocket代理
example.com {
reverse_proxy /ws/* localhost:8080
file_server
}
4.6.2 WebSocket负载均衡
ws.example.com {
reverse_proxy localhost:8080 localhost:8081 localhost:8082 {
# 使用IP哈希确保会话粘性
lb_policy ip_hash
# WebSocket特定配置
transport http {
# 保持长连接
keep_alive 0
# 禁用压缩(WebSocket自己处理)
compression off
}
}
}
4.6.3 WebSocket健康检查
ws.example.com {
reverse_proxy localhost:8080 localhost:8081 {
# HTTP健康检查(不是WebSocket)
health_uri /health
health_interval 30s
# 或者使用TCP健康检查
health_uri tcp://localhost:8080
}
}
4.7 SSL/TLS终止
4.7.1 基本SSL终止
# HTTPS到HTTP的代理
https://example.com {
reverse_proxy http://localhost:8080
}
# 自定义TLS配置
example.com {
tls {
protocols tls1.2 tls1.3
ciphers TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
}
reverse_proxy localhost:8080
}
4.7.2 客户端证书认证
example.com {
tls {
client_auth {
mode require_and_verify
trusted_ca_cert_file /path/to/ca.pem
}
}
reverse_proxy localhost:8080 {
# 传递客户端证书信息
header_up X-Client-Cert {tls_client_certificate}
header_up X-Client-Cert-Subject {tls_client_subject}
}
}
4.7.3 后端SSL代理
example.com {
reverse_proxy https://backend.internal.com {
# 后端SSL配置
transport http {
tls
tls_insecure_skip_verify
# 或者指定CA证书
# tls_ca /path/to/ca.pem
# tls_client_auth /path/to/client.pem /path/to/client.key
}
}
}
4.8 缓存配置
4.8.1 基本缓存
example.com {
reverse_proxy localhost:8080 {
# 启用缓存
@cacheable {
method GET HEAD
status 200
header Content-Type text/html
header Content-Type application/json
}
# 缓存配置
cache @cacheable {
ttl 1h
stale_ttl 24h
key {method} {host} {path} {query}
}
}
}
4.8.2 条件缓存
example.com {
reverse_proxy localhost:8080 {
# 不同内容类型的缓存策略
@static {
path *.css *.js *.png *.jpg *.gif
}
cache @static {
ttl 24h
stale_ttl 168h
}
@api {
path /api/*
method GET
}
cache @api {
ttl 5m
stale_ttl 1h
vary Accept-Encoding Authorization
}
}
}
4.8.3 缓存清除
example.com {
# 缓存清除端点
@purge {
method PURGE
path /cache/purge/*
}
handle @purge {
cache_purge {path_regexp ^/cache/purge/(.*)$ /$1}
respond "Cache purged" 200
}
reverse_proxy localhost:8080 {
cache {
ttl 1h
}
}
}
4.9 微服务架构代理
4.9.1 API网关配置
# API网关
api.example.com {
# 用户服务
handle /users/* {
reverse_proxy localhost:8001 {
header_up X-Service "users"
}
}
# 订单服务
handle /orders/* {
reverse_proxy localhost:8002 {
header_up X-Service "orders"
}
}
# 支付服务
handle /payments/* {
reverse_proxy localhost:8003 {
header_up X-Service "payments"
}
}
# 认证服务
handle /auth/* {
reverse_proxy localhost:8004 {
header_up X-Service "auth"
}
}
# 默认处理
respond "Service not found" 404
}
4.9.2 服务发现集成
# 使用环境变量的服务发现
api.example.com {
handle /users/* {
reverse_proxy {$USER_SERVICE_URL} {
health_uri /health
}
}
handle /orders/* {
reverse_proxy {$ORDER_SERVICE_URL} {
health_uri /health
}
}
}
# 使用文件的服务发现
api.example.com {
handle /users/* {
reverse_proxy `cat /etc/caddy/services/users.txt` {
health_uri /health
}
}
}
4.9.3 跨服务认证
api.example.com {
# JWT认证中间件
@authenticated {
header Authorization Bearer*
}
# 验证JWT
handle @authenticated {
# 转发到认证服务验证
reverse_proxy /auth/verify localhost:8004 {
method GET
header_up Authorization {http.request.header.Authorization}
@auth_success {
status 200
}
handle_response @auth_success {
# 认证成功,继续处理请求
request_header X-User-ID {http.response.header.X-User-ID}
request_header X-User-Role {http.response.header.X-User-Role}
}
}
}
# 业务服务代理
handle /users/* {
reverse_proxy localhost:8001
}
handle /orders/* {
reverse_proxy localhost:8002
}
}
4.10 监控和日志
4.10.1 代理日志配置
example.com {
# 详细的代理日志
log {
output file /var/log/caddy/proxy.log {
roll_size 100mb
roll_keep 10
}
format json
level INFO
}
reverse_proxy localhost:8080 {
# 添加追踪头
header_up X-Request-ID {uuid}
header_up X-Forwarded-For {remote_host}
# 记录后端响应时间
@slow {
status 2xx
header X-Response-Time >1000ms
}
handle_response @slow {
log_append {
slow_request true
backend_response_time {http.response.header.X-Response-Time}
}
}
}
}
4.10.2 健康检查监控
example.com {
reverse_proxy localhost:8080 localhost:8081 {
# 健康检查配置
health_uri /health
health_interval 10s
health_timeout 5s
# 健康状态日志
@unhealthy {
status 502 503 504
}
handle_response @unhealthy {
log_append {
backend_unhealthy true
backend_status {http.response.status}
backend_error {http.response.header.X-Error}
}
}
}
}
4.10.3 性能监控
example.com {
# 性能监控端点
handle /metrics {
metrics
}
reverse_proxy localhost:8080 {
# 添加性能头
header_up X-Start-Time {time.now.unix_nano}
# 计算响应时间
header_down X-Response-Time {time.now.unix_nano} - {http.request.header.X-Start-Time}
# 记录性能指标
@performance {
status 2xx
}
handle_response @performance {
log_append {
response_time_ns {http.response.header.X-Response-Time}
backend_server {http.reverse_proxy.upstream.address}
request_size {http.request.body.size}
response_size {http.response.body.size}
}
}
}
}
4.11 实战案例
4.11.1 高可用Web应用
# 高可用Web应用代理
app.example.com {
# 多个应用实例
reverse_proxy localhost:8080 localhost:8081 localhost:8082 {
# 负载均衡策略
lb_policy least_conn
# 健康检查
health_uri /health
health_interval 15s
health_timeout 5s
health_status 200
# 故障处理
fail_duration 30s
max_fails 3
# 会话保持(如果需要)
# lb_policy ip_hash
# 请求头
header_up X-Real-IP {remote_host}
header_up X-Forwarded-For {remote_host}
header_up X-Forwarded-Proto {scheme}
header_up X-Request-ID {uuid}
# 超时配置
transport http {
dial_timeout 10s
response_header_timeout 30s
keep_alive 30s
}
}
# 静态资源直接服务
handle /static/* {
root * /var/www/static
file_server
# 静态资源缓存
header {
Cache-Control "public, max-age=31536000"
}
}
# 错误处理
handle_errors {
@5xx {
expression {http.error.status_code} >= 500
}
rewrite @5xx /error.html
file_server {
root /var/www/errors
}
}
# 访问日志
log {
output file /var/log/caddy/app-access.log {
roll_size 100mb
roll_keep 30
}
format json
}
}
4.11.2 微服务API网关
# 微服务API网关
api.example.com {
# 全局中间件
# CORS处理
@cors_preflight {
method OPTIONS
}
handle @cors_preflight {
header {
Access-Control-Allow-Origin "*"
Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS"
Access-Control-Allow-Headers "Content-Type, Authorization"
Access-Control-Max-Age "86400"
}
respond "" 204
}
# 全局CORS头
header {
Access-Control-Allow-Origin "*"
Access-Control-Allow-Credentials "true"
}
# 认证服务
handle /auth/* {
reverse_proxy localhost:8001 localhost:8002 {
lb_policy round_robin
health_uri /health
header_up X-Service "auth"
}
}
# 用户服务(需要认证)
handle /users/* {
# JWT验证
@authenticated {
header Authorization "Bearer *"
}
# 未认证请求
respond not @authenticated "Unauthorized" 401
# 认证请求代理
reverse_proxy @authenticated localhost:8003 localhost:8004 {
lb_policy least_conn
health_uri /health
header_up X-Service "users"
header_up X-User-Token {http.request.header.Authorization}
}
}
# 产品服务(公开访问)
handle /products/* {
reverse_proxy localhost:8005 localhost:8006 {
lb_policy round_robin
health_uri /health
header_up X-Service "products"
# 缓存产品数据
@cacheable {
method GET
status 200
}
cache @cacheable {
ttl 10m
key {method} {host} {path} {query}
}
}
}
# 订单服务(需要认证)
handle /orders/* {
@authenticated {
header Authorization "Bearer *"
}
respond not @authenticated "Unauthorized" 401
reverse_proxy @authenticated localhost:8007 localhost:8008 {
lb_policy ip_hash # 会话保持
health_uri /health
header_up X-Service "orders"
}
}
# 支付服务(需要认证,高安全性)
handle /payments/* {
@authenticated {
header Authorization "Bearer *"
}
respond not @authenticated "Unauthorized" 401
# 限流
rate_limit @authenticated {
zone payments
key {remote_host}
rate 10r/m
}
reverse_proxy @authenticated localhost:8009 localhost:8010 {
lb_policy least_conn
health_uri /health
header_up X-Service "payments"
# 更严格的超时
transport http {
dial_timeout 5s
response_header_timeout 15s
}
}
}
# WebSocket服务
handle /ws/* {
reverse_proxy localhost:8011 localhost:8012 {
lb_policy ip_hash # WebSocket需要会话保持
health_uri /health
header_up X-Service "websocket"
}
}
# 文件上传服务
handle /upload/* {
@authenticated {
header Authorization "Bearer *"
}
respond not @authenticated "Unauthorized" 401
# 大文件上传配置
reverse_proxy @authenticated localhost:8013 {
header_up X-Service "upload"
transport http {
# 更长的超时时间
response_header_timeout 300s
# 更大的缓冲区
read_buffer_size 64kb
write_buffer_size 64kb
}
}
}
# 健康检查端点
handle /health {
respond "API Gateway OK" 200
}
# 默认处理
handle {
respond "API endpoint not found" 404
}
# 全局错误处理
handle_errors {
@4xx {
expression {http.error.status_code} >= 400 && {http.error.status_code} < 500
}
@5xx {
expression {http.error.status_code} >= 500
}
respond @4xx `{"error": "Client error", "status": {http.error.status_code}}` 400 {
header Content-Type "application/json"
}
respond @5xx `{"error": "Server error", "status": {http.error.status_code}}` 500 {
header Content-Type "application/json"
}
}
# 详细日志
log {
output file /var/log/caddy/api-gateway.log {
roll_size 100mb
roll_keep 30
}
format json
include http.request.method http.request.uri http.request.headers.Authorization http.response.status http.response.duration
}
}
4.11.3 容器化应用代理
# Docker容器代理
app.example.com {
# 前端应用(React/Vue等)
handle / {
reverse_proxy frontend:3000 {
header_up X-Forwarded-For {remote_host}
header_up X-Forwarded-Proto {scheme}
}
}
# API服务
handle /api/* {
reverse_proxy backend:8080 {
header_up X-Real-IP {remote_host}
header_up X-Forwarded-For {remote_host}
# 移除API前缀
rewrite /api/* /*
}
}
# 数据库管理界面
handle /admin/db/* {
# 基本认证
basicauth {
admin $2a$14$Zkx19XLiW6VYouLHR5NmfOFU0z2GTNqq9qB6FY9gZKOOdOoKw6Uw.
}
reverse_proxy adminer:8080 {
rewrite /admin/db/* /*
}
}
# 监控服务
handle /monitoring/* {
reverse_proxy prometheus:9090 grafana:3000 {
lb_policy round_robin
rewrite /monitoring/* /*
}
}
}
# 开发环境热重载
dev.example.com {
reverse_proxy localhost:3000 {
# 支持热重载的WebSocket
@websocket {
header Connection *Upgrade*
header Upgrade websocket
}
# 开发服务器通常在localhost
header_up Host localhost:3000
}
}
本章总结
本章我们深入学习了Caddy的反向代理和负载均衡功能:
- 反向代理基础:理解了反向代理的概念和优势
- 负载均衡策略:掌握了多种负载均衡算法的使用
- 高级配置:学习了请求/响应头处理、路径重写、超时配置
- 故障处理:了解了重试、熔断器、故障转移等机制
- WebSocket代理:掌握了WebSocket连接的代理配置
- SSL/TLS终止:学习了SSL终止和后端SSL代理
- 缓存配置:了解了代理层缓存的配置和管理
- 微服务架构:掌握了API网关和服务发现的实现
- 监控日志:学习了代理监控和日志配置
- 实战案例:通过实际案例巩固了所学知识
通过本章的学习,你应该能够: - 配置高性能的反向代理服务 - 实现智能的负载均衡和故障转移 - 构建微服务架构的API网关 - 优化代理性能和监控系统健康状态 - 处理复杂的企业级代理需求
练习题
基础练习
简单反向代理
- 配置基本的反向代理
- 实现多后端的负载均衡
- 添加健康检查功能
负载均衡策略
- 测试不同的负载均衡算法
- 配置带权重的后端服务器
- 实现会话保持功能
请求处理
- 配置请求头和响应头处理
- 实现路径重写功能
- 设置适当的超时配置
进阶练习
故障处理
- 配置重试和故障转移机制
- 实现熔断器功能
- 测试后端服务故障时的行为
WebSocket代理
- 配置WebSocket连接代理
- 实现WebSocket负载均衡
- 测试长连接的稳定性
SSL/TLS配置
- 配置SSL终止
- 实现客户端证书认证
- 配置后端SSL代理
实战练习
微服务API网关
- 构建完整的API网关
- 实现服务路由和认证
- 添加限流和监控功能
高可用架构
- 设计高可用的代理架构
- 实现多层故障转移
- 配置全面的监控和告警
容器化部署
- 在Docker环境中部署代理
- 配置容器间的服务发现
- 实现滚动更新和蓝绿部署
下一章我们将学习Caddy的HTTPS和安全配置,这是现代Web应用的重要组成部分。