package config import ( "strconv" "strings" "time" ) // ProxyConfig 反向代理配置,支持负载均衡和健康检查。 // // 用于将请求转发到后端服务器,支持多种负载均衡算法 // 和健康检查机制。 // // 注意事项: // - Path 使用前缀匹配,较长路径优先匹配 // - 至少配置一个 Target 才能正常工作 // - 负载均衡算法支持:round_robin、weighted_round_robin、least_conn、ip_hash、consistent_hash、random // - 一致性哈希需要配置 HashKey // // 使用示例: // // proxy: // - path: "/api/" // targets: // - url: "http://backend1:8080" // weight: 3 // - url: "http://backend2:8080" // weight: 1 // load_balance: "weighted_round_robin" // health_check: // interval: 10s // path: "/health" type ProxyConfig struct { // 指针类型字段(按大小排列) RedirectRewrite *RedirectRewriteConfig `yaml:"redirect_rewrite"` ProxySSL *ProxySSLConfig `yaml:"proxy_ssl"` CacheValid *ProxyCacheValidConfig `yaml:"cache_valid"` Buffering *ProxyBufferingConfig `yaml:"buffering"` // 切片字段 Targets []ProxyTarget `yaml:"targets"` // 字符串字段 Path string `yaml:"path"` LoadBalance string `yaml:"load_balance"` HashKey string `yaml:"hash_key"` ClientMaxBodySize string `yaml:"client_max_body_size"` ProxyBind string `yaml:"proxy_bind"` // 结构体字段 Headers ProxyHeaders `yaml:"headers"` BalancerByLua BalancerByLuaConfig `yaml:"balancer_by_lua"` HealthCheck HealthCheckConfig `yaml:"health_check"` NextUpstream NextUpstreamConfig `yaml:"next_upstream"` Cache ProxyCacheConfig `yaml:"cache"` Timeout ProxyTimeout `yaml:"timeout"` // 基本类型字段 VirtualNodes int `yaml:"virtual_nodes"` // LocationType 位置匹配类型 // 可选值:exact、prefix_priority、regex、regex_caseless、prefix、named LocationType string `yaml:"location_type"` // LocationName 位置名称 // 仅当 LocationType 为 named 时使用,用于命名位置块 LocationName string `yaml:"location_name"` // Internal 仅允许内部访问 // 设置为 true 时,该位置仅允许内部重定向访问 Internal bool `yaml:"internal"` } // ProxyBufferingConfig 代理缓冲配置。 // // 控制代理响应的缓冲行为: // - "default" 或 "on": 缓冲响应到内存/临时文件 // - "off": 流式转发响应,不缓冲 // // 使用示例: // // buffering: // mode: "off" type ProxyBufferingConfig struct { // Mode 缓冲模式 // 可选值:"default"(默认缓冲), "on"(强制缓冲), "off"(关闭缓冲) Mode string `yaml:"mode"` // BufferSize 响应缓冲区大小(字节) // 0 表示使用默认值 BufferSize int `yaml:"buffer_size"` // Buffers 多缓冲区配置字符串 // 格式:"数量 大小" 或 "数量1 大小1 数量2 大小2 ..." // 例如:"8 16k" 表示 8 个 16KB 缓冲区 // 例如:"4 4k 8 16k" 表示 4 个 4KB + 8 个 16KB 缓冲区 Buffers string `yaml:"buffers"` // BufferCount 缓冲区数量(解析后) BufferCount int `yaml:"-"` // BufferSizeEach 每个缓冲区大小(字节,解析后) BufferSizeEach int `yaml:"-"` } // ParseBuffers 解析 Buffers 配置字符串。 // // 支持格式: // - "8 16k" → 8 个 16KB 缓冲区 // - "4 4k" → 4 个 4KB 缓冲区 // // 大小单位: // - k 或 K: KB (1024 字节) // - m 或 M: MB (1024 * 1024 字节) // - 无单位: 字节 func (c *ProxyBufferingConfig) ParseBuffers() { if c.Buffers == "" { // 向后兼容:使用 BufferSize if c.BufferSize > 0 { c.BufferCount = 1 c.BufferSizeEach = c.BufferSize } return } parts := strings.Fields(c.Buffers) if len(parts) < 2 { return // 无效格式 } count, err := strconv.Atoi(parts[0]) if err != nil || count <= 0 { return // 无效数量 } sizeEach, err := parseSize(parts[1]) if err != nil || sizeEach <= 0 { return // 无效大小 } c.BufferCount = count c.BufferSizeEach = sizeEach } // BalancerByLuaConfig Lua 负载均衡配置 // // 使用 Lua 脚本动态选择后端目标,支持自定义负载均衡逻辑。 // // 注意事项: // - Script 为 Lua 脚本文件路径 // - Timeout 控制脚本执行超时 // - Fallback 指定 Lua 失败时的备用算法 // // 使用示例: // // balancer_by_lua: // enabled: true // script: "/etc/lolly/scripts/balancer.lua" // timeout: 100ms // fallback: "round_robin" type BalancerByLuaConfig struct { // Script Lua 脚本路径 Script string `yaml:"script"` // Fallback 失败时使用的默认负载均衡算法 // 默认值: "round_robin" Fallback string `yaml:"fallback"` // Timeout 执行超时 // 默认值: 100ms Timeout time.Duration `yaml:"timeout"` // Enabled 是否启用 Enabled bool `yaml:"enabled"` } // ProxyTarget 后端目标配置。 // // 定义单个后端服务器的地址和权重。 // // 注意事项: // - URL 必须包含协议(http:// 或 https://) // - Weight 仅在 weighted_round_robin 算法下生效 // // 使用示例: // // targets: // - url: "http://backend1:8080" // weight: 3 // - url: "http://backend2:8080" // weight: 1 type ProxyTarget struct { // URL 后端地址 // 格式:"http://host:port" 或 "https://host:port" URL string `yaml:"url"` // Weight 权重 // 用于加权轮询算法,值越大分配的请求越多 Weight int `yaml:"weight"` // MaxConns 最大并发连接数 // 0 表示不限制 MaxConns int `yaml:"max_conns"` // MaxFails 最大失败次数 // 在 FailTimeout 期间失败次数达到此值后标记为不可用 // 0 表示不进行被动失败检测 MaxFails int `yaml:"max_fails"` // FailTimeout 失败超时时间 // 达到 MaxFails 后,目标在此时间内被视为不可用 FailTimeout time.Duration `yaml:"fail_timeout"` // Backup 备份服务器 // 仅当所有非备份服务器不可用时才使用 Backup bool `yaml:"backup"` // Down 标记服务器为永久不可用 Down bool `yaml:"down"` // ProxyURI 代理传递的 URI 路径 // 设置后替换请求路径,支持 nginx proxy_pass URI 语义 ProxyURI string `yaml:"proxy_uri"` } // HealthCheckConfig 健康检查配置。 // // 定期检查后端服务器的健康状态,自动剔除不健康的节点。 // // 注意事项: // - Interval 不宜设置过小,避免增加后端负担 // - Path 应该是轻量级的健康检查端点 // - 超时时间应小于检查间隔 // // 使用示例: // // health_check: // interval: 10s // path: "/health" // timeout: 5s type HealthCheckConfig struct { Path string `yaml:"path"` Interval time.Duration `yaml:"interval"` Timeout time.Duration `yaml:"timeout"` Match *HealthMatchConfig `yaml:"match"` // 健康检查匹配配置 SlowStart time.Duration `yaml:"slow_start"` // 慢启动时间 } // HealthMatchConfig 健康检查匹配配置。 type HealthMatchConfig struct { Status []string `yaml:"status"` // 状态码范围列表 Body string `yaml:"body"` // 响应体正则表达式 Headers map[string]string `yaml:"headers"` // 响应头匹配 } // ProxyTimeout 代理超时配置。 // // 控制代理请求的各个阶段超时。 // // 注意事项: // - Connect 超时包括 DNS 解析和 TCP 连接建立 // - Read 和 Write 超时分别控制响应读取和请求发送 // - 超时时间需要根据后端服务响应时间调整 // // 使用示例: // // timeout: // connect: 5s // read: 30s // write: 30s type ProxyTimeout struct { // Connect 连接超时 // 建立到后端服务器的连接超时 Connect time.Duration `yaml:"connect"` // Read 读取超时 // 从后端读取响应的超时 Read time.Duration `yaml:"read"` // Write 写入超时 // 向后端发送请求的超时 Write time.Duration `yaml:"write"` } // ProxyHeaders 代理请求/响应头配置。 // // 在代理转发过程中修改 HTTP 头部。 // // 注意事项: // - SetRequest 添加/修改发送到后端的请求头 // - SetResponse 添加/修改返回给客户端的响应头 // - Remove 会删除指定的请求头(在发送到后端之前) // // 使用示例: // // headers: // set_request: // X-Forwarded-For: "$remote_addr" // X-Real-IP: "$remote_addr" // set_response: // X-Proxy-By: "lolly" // remove: // - "X-Internal-Header" type ProxyHeaders struct { // SetRequest 设置请求头 // 发送到后端的请求中添加或覆盖的头部 SetRequest map[string]string `yaml:"set_request"` // SetResponse 设置响应头 // 返回给客户端的响应中添加或覆盖的头部 SetResponse map[string]string `yaml:"set_response"` // Remove 移除的头部 // 从发送到后端的请求中移除的头部列表 Remove []string `yaml:"remove"` // HideResponse 隐藏的响应头 // 从返回给客户端的响应中移除的头部列表 HideResponse []string `yaml:"hide_response"` // PassResponse 允许传递的响应头 // 仅传递列出的头部,其他全部隐藏(白名单模式) PassResponse []string `yaml:"pass_response"` // IgnoreHeaders 忽略的头部 // 代理时完全忽略这些头部,不转发到后端也不返回给客户端 IgnoreHeaders []string `yaml:"ignore_headers"` // CookieDomain Cookie 域重写 // 将响应中 Set-Cookie 的 domain 替换为此值 CookieDomain string `yaml:"cookie_domain"` // CookiePath Cookie 路径重写 // 将响应中 Set-Cookie 的 path 替换为此值 CookiePath string `yaml:"cookie_path"` } // ProxySSLConfig 上游 SSL/TLS 配置。 // // 配置代理连接上游服务器时的 TLS 行为,支持自定义 CA、客户端证书(mTLS)、 // SNI 和 TLS 版本控制。 // // 注意事项: // - Enabled 为 true 时启用自定义 TLS 配置 // - TrustedCA 用于验证上游服务器证书 // - ClientCert + ClientKey 用于 mTLS 客户端认证 // - InsecureSkipVerify 仅用于测试,生产环境禁用 // // 使用示例: // // proxy_ssl: // enabled: true // server_name: "api.internal" // trusted_ca: "/etc/ssl/ca/upstream-ca.crt" // client_cert: "/etc/ssl/client.crt" // client_key: "/etc/ssl/client.key" // min_version: "TLSv1.2" type ProxySSLConfig struct { // 字符串字段 ServerName string `yaml:"server_name"` TrustedCA string `yaml:"trusted_ca"` ClientCert string `yaml:"client_cert"` ClientKey string `yaml:"client_key"` MinVersion string `yaml:"min_version"` MaxVersion string `yaml:"max_version"` // 布尔字段 Enabled bool `yaml:"enabled"` InsecureSkipVerify bool `yaml:"insecure_skip_verify"` } // RedirectRewriteConfig Location/Refresh 头改写配置 // // 用于配置代理响应中 Location 和 Refresh 头的改写行为。 // // 注意事项: // - Mode 支持 "default"、"off"、"custom" 三种模式 // - 未配置或空字符串时默认为 "default" 模式 // - "custom" 模式必须配置至少一条规则 // // 使用示例: // // redirect_rewrite: // mode: "default" # 或 "off" 或 "custom" // rules: // - pattern: "http://backend:8000/" // replacement: "$scheme://$host:$server_port/" type RedirectRewriteConfig struct { // Mode 运行模式: "default" | "off" | "custom" // default: 自动从选中的 target URL 生成规则(运行时) // off: 禁用改写 // custom: 使用 Rules 列表(预编译) // 未配置或空字符串时默认为 "default" Mode string `yaml:"mode"` // Rules 改写规则列表,仅在 Mode="custom" 时使用 Rules []RedirectRewriteRule `yaml:"rules"` } // RedirectRewriteRule 单条改写规则 // // 定义 Location/Refresh 头改写的匹配模式和替换目标。 // // 注意事项: // - Pattern 以 ~ 开头表示正则,~* 表示大小写不敏感 // - 无 ~ 前缀时使用前缀匹配语义 // - Replacement 支持变量展开($host, $scheme, $server_port 等) // // 使用示例: // // rules: // - pattern: "http://backend:8000/" // replacement: "$scheme://$host:$server_port/" // - pattern: "~^http://[^/]+:8000/(.*)$" // replacement: "$scheme://$host/$1" type RedirectRewriteRule struct { // Pattern 匹配模式,支持正则(以 ~ 开头)或精确匹配 // 示例: "http://localhost:8000/" 或 "~^http://[^/]+:8000/" Pattern string `yaml:"pattern"` // Replacement 替换目标,支持变量展开 // 示例: "$scheme://$host:$server_port/" 或 "/" Replacement string `yaml:"replacement"` } // NextUpstreamConfig 故障转移配置,定义后端失败时的自动重试行为。 // // 当后端返回特定错误状态码或连接失败时,自动尝试下一个可用后端。 // // 注意事项: // - Tries 为 1 时禁用故障转移 // - 空 NextUpstream 使用默认值(Tries=1,禁用故障转移) // - 建议根据后端数量合理设置 Tries 值 // // 使用示例: // // next_upstream: // tries: 3 // http_codes: [502, 503, 504] type NextUpstreamConfig struct { HTTPCodes []int `yaml:"http_codes"` Tries int `yaml:"tries"` }