feat(config): add Least Time and Sticky configuration support
- Add least_time and sticky to valid algorithms list - Add LeastTimeConfig and StickyConfig structures - Update default config generation with new options - Add configuration validation for new fields
This commit is contained in:
parent
a73da4e14a
commit
88a2c1fc1b
@ -397,7 +397,7 @@ func GenerateConfigYAML(cfg *Config) ([]byte, error) {
|
|||||||
buf.WriteString(" # backup: false # 备份服务器标记(仅当主服务器不可用时使用)\n")
|
buf.WriteString(" # backup: false # 备份服务器标记(仅当主服务器不可用时使用)\n")
|
||||||
buf.WriteString(" # down: false # 永久不可用标记\n")
|
buf.WriteString(" # down: false # 永久不可用标记\n")
|
||||||
buf.WriteString(" # proxy_uri: \"\" # 代理传递的 URI 路径\n")
|
buf.WriteString(" # proxy_uri: \"\" # 代理传递的 URI 路径\n")
|
||||||
buf.WriteString(" # load_balance: round_robin # 负载均衡算法(有效值: round_robin, weighted_round_robin, least_conn, ip_hash, consistent_hash, random)\n")
|
buf.WriteString(" # load_balance: round_robin # 负载均衡算法(有效值: round_robin, weighted_round_robin, least_conn, ip_hash, consistent_hash, random, least_time, sticky)\n")
|
||||||
buf.WriteString(" # hash_key: ip # 一致性哈希键(仅 load_balance=consistent_hash 时有效,有效值: ip, uri, header:X-Name)\n")
|
buf.WriteString(" # hash_key: ip # 一致性哈希键(仅 load_balance=consistent_hash 时有效,有效值: ip, uri, header:X-Name)\n")
|
||||||
buf.WriteString(" # virtual_nodes: 150 # 一致性哈希虚拟节点数(仅 load_balance=consistent_hash 时有效)\n")
|
buf.WriteString(" # virtual_nodes: 150 # 一致性哈希虚拟节点数(仅 load_balance=consistent_hash 时有效)\n")
|
||||||
buf.WriteString(" # health_check: # 健康检查\n")
|
buf.WriteString(" # health_check: # 健康检查\n")
|
||||||
@ -480,6 +480,17 @@ func GenerateConfigYAML(cfg *Config) ([]byte, error) {
|
|||||||
buf.WriteString(" # # replacement: \"$scheme://$host:$server_port/\" # 替换目标(支持 $host, $scheme, $server_port 等变量)\n")
|
buf.WriteString(" # # replacement: \"$scheme://$host:$server_port/\" # 替换目标(支持 $host, $scheme, $server_port 等变量)\n")
|
||||||
buf.WriteString(" # # - pattern: \"~^http://[^/]+:8000/(.*)$\" # 正则匹配示例\n")
|
buf.WriteString(" # # - pattern: \"~^http://[^/]+:8000/(.*)$\" # 正则匹配示例\n")
|
||||||
buf.WriteString(" # # replacement: \"$scheme://$host/$1\" # 使用捕获组 $1\n")
|
buf.WriteString(" # # replacement: \"$scheme://$host/$1\" # 使用捕获组 $1\n")
|
||||||
|
buf.WriteString(" # least_time: # 最小时间负载均衡配置\n")
|
||||||
|
buf.WriteString(" # metric: last_byte # 指标类型(header | last_byte)\n")
|
||||||
|
buf.WriteString(" # default_time: 1ms # 无统计样本时的默认响应时间\n")
|
||||||
|
buf.WriteString(" # sticky: # Session Sticky 配置\n")
|
||||||
|
buf.WriteString(" # enabled: false # 是否启用\n")
|
||||||
|
buf.WriteString(" # name: lolly_route # cookie 名称\n")
|
||||||
|
buf.WriteString(" # expires: 1h # session 有效期\n")
|
||||||
|
buf.WriteString(" # path: / # cookie 路径\n")
|
||||||
|
buf.WriteString(" # http_only: true # HttpOnly flag\n")
|
||||||
|
buf.WriteString(" # same_site: Lax # SameSite 属性\n")
|
||||||
|
buf.WriteString(" # fallback_balance: round_robin # fallback 算法\n")
|
||||||
buf.WriteString("\n")
|
buf.WriteString("\n")
|
||||||
|
|
||||||
// SSL 配置
|
// SSL 配置
|
||||||
|
|||||||
@ -19,7 +19,7 @@ import (
|
|||||||
// 注意事项:
|
// 注意事项:
|
||||||
// - Path 使用前缀匹配,较长路径优先匹配
|
// - Path 使用前缀匹配,较长路径优先匹配
|
||||||
// - 至少配置一个 Target 才能正常工作
|
// - 至少配置一个 Target 才能正常工作
|
||||||
// - 负载均衡算法支持:round_robin、weighted_round_robin、least_conn、ip_hash、consistent_hash、random
|
// - 负载均衡算法支持:round_robin、weighted_round_robin、least_conn、ip_hash、consistent_hash、random、least_time、sticky
|
||||||
// - 一致性哈希需要配置 HashKey
|
// - 一致性哈希需要配置 HashKey
|
||||||
//
|
//
|
||||||
// 使用示例:
|
// 使用示例:
|
||||||
@ -56,6 +56,8 @@ type ProxyConfig struct {
|
|||||||
NextUpstream NextUpstreamConfig `yaml:"next_upstream"`
|
NextUpstream NextUpstreamConfig `yaml:"next_upstream"`
|
||||||
Cache ProxyCacheConfig `yaml:"cache"`
|
Cache ProxyCacheConfig `yaml:"cache"`
|
||||||
Timeout ProxyTimeout `yaml:"timeout"`
|
Timeout ProxyTimeout `yaml:"timeout"`
|
||||||
|
LeastTime LeastTimeConfig `yaml:"least_time"`
|
||||||
|
Sticky StickyConfig `yaml:"sticky"`
|
||||||
// 基本类型字段
|
// 基本类型字段
|
||||||
VirtualNodes int `yaml:"virtual_nodes"`
|
VirtualNodes int `yaml:"virtual_nodes"`
|
||||||
|
|
||||||
@ -440,6 +442,77 @@ type RedirectRewriteRule struct {
|
|||||||
Replacement string `yaml:"replacement"`
|
Replacement string `yaml:"replacement"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// LeastTimeConfig 最小时间负载均衡配置。
|
||||||
|
//
|
||||||
|
// 基于后端响应时间选择最优后端。
|
||||||
|
//
|
||||||
|
// 注意事项:
|
||||||
|
// - Metric 决定时间统计方式
|
||||||
|
// - DefaultTime 用于首次请求无样本时
|
||||||
|
//
|
||||||
|
// 使用示例:
|
||||||
|
//
|
||||||
|
// least_time:
|
||||||
|
// metric: last_byte # 指标类型(header | last_byte)
|
||||||
|
// default_time: 1ms # 无统计样本时的默认响应时间
|
||||||
|
type LeastTimeConfig struct {
|
||||||
|
// Metric 时间指标类型
|
||||||
|
// 可选值:header(首字节时间)、last_byte(末字节时间)
|
||||||
|
Metric string `yaml:"metric"`
|
||||||
|
|
||||||
|
// DefaultTime 无统计样本时的默认响应时间
|
||||||
|
// 用于首次请求或新后端加入时
|
||||||
|
DefaultTime time.Duration `yaml:"default_time"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// StickyConfig Session Sticky 配置。
|
||||||
|
//
|
||||||
|
// 通过 Cookie 将同一客户端固定到同一后端。
|
||||||
|
//
|
||||||
|
// 注意事项:
|
||||||
|
// - Enabled 为 true 时启用
|
||||||
|
// - FallbackAlgo 指定当无法找到 sticky 后端时使用的算法
|
||||||
|
//
|
||||||
|
// 使用示例:
|
||||||
|
//
|
||||||
|
// sticky:
|
||||||
|
// enabled: true
|
||||||
|
// name: lolly_route # cookie 名称
|
||||||
|
// expires: 1h # session 有效期
|
||||||
|
// path: / # cookie 路径
|
||||||
|
// http_only: true # HttpOnly flag
|
||||||
|
// same_site: Lax # SameSite 属性
|
||||||
|
// fallback_balance: round_robin # fallback 算法
|
||||||
|
type StickyConfig struct {
|
||||||
|
// Enabled 是否启用 Session Sticky
|
||||||
|
Enabled bool `yaml:"enabled"`
|
||||||
|
|
||||||
|
// Name Cookie 名称
|
||||||
|
Name string `yaml:"name"`
|
||||||
|
|
||||||
|
// Expires session 有效期
|
||||||
|
Expires time.Duration `yaml:"expires"`
|
||||||
|
|
||||||
|
// Domain Cookie 域
|
||||||
|
Domain string `yaml:"domain"`
|
||||||
|
|
||||||
|
// Path Cookie 路径
|
||||||
|
Path string `yaml:"path"`
|
||||||
|
|
||||||
|
// Secure Secure flag
|
||||||
|
Secure bool `yaml:"secure"`
|
||||||
|
|
||||||
|
// HttpOnly HttpOnly flag
|
||||||
|
HttpOnly bool `yaml:"http_only"`
|
||||||
|
|
||||||
|
// SameSite SameSite 属性
|
||||||
|
// 可选值:Lax, Strict, None
|
||||||
|
SameSite string `yaml:"same_site"`
|
||||||
|
|
||||||
|
// FallbackAlgo 无法找到 sticky 后端时的 fallback 算法
|
||||||
|
FallbackAlgo string `yaml:"fallback_balance"`
|
||||||
|
}
|
||||||
|
|
||||||
// NextUpstreamConfig 故障转移配置,定义后端失败时的自动重试行为。
|
// NextUpstreamConfig 故障转移配置,定义后端失败时的自动重试行为。
|
||||||
//
|
//
|
||||||
// 当后端返回特定错误状态码或连接失败时,自动尝试下一个可用后端。
|
// 当后端返回特定错误状态码或连接失败时,自动尝试下一个可用后端。
|
||||||
|
|||||||
@ -504,6 +504,23 @@ func validateProxy(p *ProxyConfig) error {
|
|||||||
return fmt.Errorf("无效的负载均衡算法:%s", p.LoadBalance)
|
return fmt.Errorf("无效的负载均衡算法:%s", p.LoadBalance)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// validate least_time config
|
||||||
|
if p.LoadBalance == "least_time" {
|
||||||
|
if p.LeastTime.Metric != "" && p.LeastTime.Metric != "header" && p.LeastTime.Metric != "last_byte" {
|
||||||
|
return fmt.Errorf("无效的 least_time metric: %s(有效值: header, last_byte)", p.LeastTime.Metric)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// validate sticky config
|
||||||
|
if p.LoadBalance == "sticky" {
|
||||||
|
if !p.Sticky.Enabled {
|
||||||
|
return fmt.Errorf("load_balance=sticky 时 sticky.enabled 必须为 true")
|
||||||
|
}
|
||||||
|
if p.Sticky.FallbackAlgo != "" && !loadbalance.IsValidAlgorithm(p.Sticky.FallbackAlgo) {
|
||||||
|
return fmt.Errorf("无效的 sticky fallback_balance: %s", p.Sticky.FallbackAlgo)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 验证故障转移配置
|
// 验证故障转移配置
|
||||||
if err := validateNextUpstream(&p.NextUpstream); err != nil {
|
if err := validateNextUpstream(&p.NextUpstream); err != nil {
|
||||||
return fmt.Errorf("next_upstream: %w", err)
|
return fmt.Errorf("next_upstream: %w", err)
|
||||||
|
|||||||
@ -24,6 +24,8 @@ var validAlgorithms = []string{
|
|||||||
"ip_hash",
|
"ip_hash",
|
||||||
"consistent_hash",
|
"consistent_hash",
|
||||||
"random",
|
"random",
|
||||||
|
"least_time",
|
||||||
|
"sticky",
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsValidAlgorithm 检查给定的算法名称是否有效。
|
// IsValidAlgorithm 检查给定的算法名称是否有效。
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user