4.1 反向代理概述

4.1.1 什么是反向代理

反向代理是一种代理服务器,它代表服务器接收客户端的请求,然后将请求转发给后端服务器,并将后端服务器的响应返回给客户端。与正向代理不同,反向代理对客户端是透明的。

4.1.2 反向代理的优势

  1. 负载均衡:将请求分发到多个后端服务器
  2. SSL终止:在代理层处理SSL/TLS加密
  3. 缓存:缓存后端响应,提高性能
  4. 压缩:压缩响应内容,减少带宽使用
  5. 安全性:隐藏后端服务器的真实信息
  6. 高可用性:提供故障转移和健康检查
  7. 统一入口:为多个服务提供统一的访问入口

4.1.3 Caddy反向代理的特点

  1. 零配置负载均衡:自动健康检查和故障转移
  2. 多种负载均衡算法:支持轮询、最少连接、IP哈希等
  3. HTTP/2和HTTP/3支持:现代协议支持
  4. WebSocket支持:透明的WebSocket代理
  5. 自动重试:智能的请求重试机制
  6. 流式传输:支持大文件和流媒体代理

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的反向代理和负载均衡功能:

  1. 反向代理基础:理解了反向代理的概念和优势
  2. 负载均衡策略:掌握了多种负载均衡算法的使用
  3. 高级配置:学习了请求/响应头处理、路径重写、超时配置
  4. 故障处理:了解了重试、熔断器、故障转移等机制
  5. WebSocket代理:掌握了WebSocket连接的代理配置
  6. SSL/TLS终止:学习了SSL终止和后端SSL代理
  7. 缓存配置:了解了代理层缓存的配置和管理
  8. 微服务架构:掌握了API网关和服务发现的实现
  9. 监控日志:学习了代理监控和日志配置
  10. 实战案例:通过实际案例巩固了所学知识

通过本章的学习,你应该能够: - 配置高性能的反向代理服务 - 实现智能的负载均衡和故障转移 - 构建微服务架构的API网关 - 优化代理性能和监控系统健康状态 - 处理复杂的企业级代理需求

练习题

基础练习

  1. 简单反向代理

    • 配置基本的反向代理
    • 实现多后端的负载均衡
    • 添加健康检查功能
  2. 负载均衡策略

    • 测试不同的负载均衡算法
    • 配置带权重的后端服务器
    • 实现会话保持功能
  3. 请求处理

    • 配置请求头和响应头处理
    • 实现路径重写功能
    • 设置适当的超时配置

进阶练习

  1. 故障处理

    • 配置重试和故障转移机制
    • 实现熔断器功能
    • 测试后端服务故障时的行为
  2. WebSocket代理

    • 配置WebSocket连接代理
    • 实现WebSocket负载均衡
    • 测试长连接的稳定性
  3. SSL/TLS配置

    • 配置SSL终止
    • 实现客户端证书认证
    • 配置后端SSL代理

实战练习

  1. 微服务API网关

    • 构建完整的API网关
    • 实现服务路由和认证
    • 添加限流和监控功能
  2. 高可用架构

    • 设计高可用的代理架构
    • 实现多层故障转移
    • 配置全面的监控和告警
  3. 容器化部署

    • 在Docker环境中部署代理
    • 配置容器间的服务发现
    • 实现滚动更新和蓝绿部署

下一章我们将学习Caddy的HTTPS和安全配置,这是现代Web应用的重要组成部分。