- Fix FD leak in DupListener: close *os.File after net.FileListener - Add cleanup of partially-duped listeners on DupListener failure - Make reload timeout configurable via shutdown.reload_timeout - Handle filepath.Abs errors in processIncludes instead of ignoring - Use net.ParseIP in isAnyAddr for robust IPv6 support
264 lines
7.7 KiB
Go
264 lines
7.7 KiB
Go
package config
|
||
|
||
import (
|
||
"errors"
|
||
"fmt"
|
||
"net"
|
||
"time"
|
||
)
|
||
|
||
// HTTP2Config HTTP/2 配置。
|
||
//
|
||
// HTTP/2 提供多路复用、头部压缩和服务器推送等功能,
|
||
// 需要服务器配置 SSL/TLS 证书才能正常工作。
|
||
//
|
||
// 注意事项:
|
||
// - 必须配置有效的 SSL 证书(TLS 1.2 或更高版本)
|
||
// - http2.enabled 仅在配置了 SSL/TLS 时生效
|
||
// - 客户端可以通过 ALPN 协商使用 HTTP/2 或 HTTP/1.1
|
||
//
|
||
// 使用示例:
|
||
//
|
||
// server:
|
||
// ssl:
|
||
// cert: "/etc/ssl/server.crt"
|
||
// key: "/etc/ssl/server.key"
|
||
// http2:
|
||
// enabled: true
|
||
// max_concurrent_streams: 128
|
||
// max_header_list_size: "16KB"
|
||
type HTTP2Config struct {
|
||
MaxConcurrentStreams int `yaml:"max_concurrent_streams"`
|
||
MaxHeaderListSize int `yaml:"max_header_list_size"`
|
||
IdleTimeout time.Duration `yaml:"idle_timeout"`
|
||
Enabled bool `yaml:"enabled"`
|
||
PushEnabled bool `yaml:"push_enabled"`
|
||
H2CEnabled bool `yaml:"h2c_enabled"`
|
||
GracefulShutdownTimeout time.Duration `yaml:"graceful_shutdown_timeout"`
|
||
}
|
||
|
||
// HTTP3Config HTTP/3 (QUIC) 配置。
|
||
//
|
||
// HTTP/3 基于 QUIC 协议,提供更快的连接建立和更低的延迟。
|
||
// 需要服务器配置 SSL/TLS 证书才能正常工作。
|
||
//
|
||
// 注意事项:
|
||
// - 必须配置有效的 SSL 证书
|
||
// - UDP 监听地址不能与 HTTP/1.1 或 HTTP/2 冲突
|
||
// - 0-RTT 特性可能带来重放攻击风险,需评估安全性
|
||
// - 部分网络环境可能限制 UDP 流量
|
||
//
|
||
// 使用示例:
|
||
//
|
||
// http3:
|
||
// enabled: true
|
||
// listen: ":443"
|
||
// max_streams: 1000
|
||
// idle_timeout: 30s
|
||
// enable_0rtt: true
|
||
type HTTP3Config struct {
|
||
Listen string `yaml:"listen"`
|
||
MaxStreams int `yaml:"max_streams"`
|
||
IdleTimeout time.Duration `yaml:"idle_timeout"`
|
||
Enabled bool `yaml:"enabled"`
|
||
Enable0RTT bool `yaml:"enable_0rtt"`
|
||
}
|
||
|
||
// PerformanceConfig 性能配置。
|
||
//
|
||
// 配置服务器性能优化相关参数。
|
||
//
|
||
// 注意事项:
|
||
// - GoroutinePool 复用 goroutine 减少创建开销
|
||
// - FileCache 缓存静态文件内容提升响应速度
|
||
// - Transport 配置代理连接的连接池参数
|
||
//
|
||
// 使用示例:
|
||
//
|
||
// performance:
|
||
// goroutine_pool:
|
||
// enabled: true
|
||
// max_workers: 1000
|
||
// file_cache:
|
||
// max_entries: 10000
|
||
// max_size: 1073741824
|
||
// transport:
|
||
// max_idle_conns: 100
|
||
type PerformanceConfig struct {
|
||
// GoroutinePool Goroutine 池配置
|
||
// 控制 worker goroutine 的复用行为
|
||
GoroutinePool GoroutinePoolConfig `yaml:"goroutine_pool"`
|
||
|
||
// FileCache 文件缓存配置
|
||
// 缓存静态文件内容避免重复磁盘 IO
|
||
FileCache FileCacheConfig `yaml:"file_cache"`
|
||
|
||
// Transport HTTP Transport 配置
|
||
// 代理连接池的参数设置
|
||
Transport TransportConfig `yaml:"transport"`
|
||
}
|
||
|
||
// GoroutinePoolConfig Goroutine 池配置。
|
||
//
|
||
// 复用 goroutine 减少创建和销毁开销。
|
||
//
|
||
// 注意事项:
|
||
// - Enabled 为 true 时启用 goroutine 池
|
||
// - MaxWorkers 限制最大并发 worker 数
|
||
// - MinWorkers 预热 worker 数量
|
||
// - IdleTimeout 空闲 worker 回收时间
|
||
//
|
||
// 使用示例:
|
||
//
|
||
// goroutine_pool:
|
||
// enabled: true
|
||
// max_workers: 1000
|
||
// min_workers: 100
|
||
// idle_timeout: 60s
|
||
type GoroutinePoolConfig struct {
|
||
// Enabled 是否启用
|
||
Enabled bool `yaml:"enabled"`
|
||
|
||
// MaxWorkers 最大 worker 数
|
||
// 限制同时运行的最大 goroutine 数量
|
||
MaxWorkers int `yaml:"max_workers"`
|
||
|
||
// MinWorkers 最小 worker 数(预热)
|
||
// 启动时预创建的 goroutine 数量
|
||
MinWorkers int `yaml:"min_workers"`
|
||
|
||
// IdleTimeout 空闲超时
|
||
// 空闲 worker 超过此时间将被回收
|
||
IdleTimeout time.Duration `yaml:"idle_timeout"`
|
||
}
|
||
|
||
// TransportConfig HTTP Transport 配置。
|
||
//
|
||
// 配置代理后端连接的连接池参数。
|
||
//
|
||
// 注意事项:
|
||
// - IdleConnTimeout 控制空闲连接的保持时间
|
||
// - MaxConnsPerHost 限制每个后端主机的总连接数(含活跃和空闲)
|
||
//
|
||
// 使用示例:
|
||
//
|
||
// transport:
|
||
// idle_conn_timeout: 90s
|
||
// max_conns_per_host: 100
|
||
type TransportConfig struct {
|
||
// IdleConnTimeout 空闲连接超时
|
||
// 空闲连接的最大存活时间
|
||
IdleConnTimeout time.Duration `yaml:"idle_conn_timeout"`
|
||
|
||
// MaxConnsPerHost 每主机最大连接数
|
||
// 单个后端主机的总连接数上限(包括活跃连接和空闲连接)
|
||
MaxConnsPerHost int `yaml:"max_conns_per_host"`
|
||
}
|
||
|
||
// ShutdownConfig 服务器关闭配置。
|
||
//
|
||
// 用于配置服务器在接收到不同信号时的关闭超时行为。
|
||
// 优雅停止会等待正在处理的请求完成,快速停止会立即中断连接。
|
||
//
|
||
// 注意事项:
|
||
// - graceful_timeout = 0 表示使用默认值(30s)
|
||
// - fast_timeout = 0 表示使用默认值(5s)
|
||
// - graceful_timeout 应显著大于 fast_timeout
|
||
// - 两个值都必须 >= 0,负数在验证时会报错
|
||
//
|
||
// 使用示例:
|
||
//
|
||
// shutdown:
|
||
// graceful_timeout: 30s # SIGQUIT 优雅停止超时
|
||
// fast_timeout: 5s # SIGINT/SIGTERM 快速停止超时
|
||
type ShutdownConfig struct {
|
||
// GracefulTimeout 优雅停止超时(SIGQUIT)
|
||
// 接收到 SIGQUIT 信号后,等待活跃请求完成的最大时间
|
||
// 默认: 30s(当值为 0 时使用默认值)
|
||
GracefulTimeout time.Duration `yaml:"graceful_timeout"`
|
||
|
||
// FastTimeout 快速停止超时(SIGINT/SIGTERM)
|
||
// 接收到 SIGINT 或 SIGTERM 信号后,等待服务器关闭的最大时间
|
||
// 默认: 5s(当值为 0 时使用默认值)
|
||
FastTimeout time.Duration `yaml:"fast_timeout"`
|
||
|
||
// ReloadTimeout 热重载启动等待超时(SIGHUP)
|
||
// 等待新服务器启动完成的最大时间,超时后视为启动成功
|
||
// 默认: 5s(当值为 0 时使用默认值)
|
||
ReloadTimeout time.Duration `yaml:"reload_timeout"`
|
||
}
|
||
|
||
// ResolverConfig DNS 解析器配置。
|
||
//
|
||
// 配置 DNS 解析器的行为,包括服务器地址、缓存 TTL、超时等。
|
||
// 启用后可实现动态 DNS 解析和缓存,支持后端域名的动态解析。
|
||
//
|
||
// 注意事项:
|
||
// - Enabled 为 true 时启用 DNS 解析器
|
||
// - Addresses 配置 DNS 服务器地址,如 "8.8.8.8:53"
|
||
// - Valid 为缓存有效期(TTL),建议 30s-300s
|
||
// - Timeout 为单次查询超时时间
|
||
//
|
||
// 使用示例:
|
||
//
|
||
// resolver:
|
||
// enabled: true
|
||
// addresses:
|
||
// - "8.8.8.8:53"
|
||
// - "8.8.4.4:53"
|
||
// valid: 30s
|
||
// timeout: 5s
|
||
// ipv4: true
|
||
// ipv6: false
|
||
// cache_size: 1024
|
||
type ResolverConfig struct {
|
||
Addresses []string `yaml:"addresses"`
|
||
Valid time.Duration `yaml:"valid"`
|
||
Timeout time.Duration `yaml:"timeout"`
|
||
CacheSize int `yaml:"cache_size"`
|
||
Enabled bool `yaml:"enabled"`
|
||
IPv4 bool `yaml:"ipv4"`
|
||
IPv6 bool `yaml:"ipv6"`
|
||
}
|
||
|
||
// TTL 返回缓存有效期(Valid 的别名,便于代码理解)。
|
||
func (c *ResolverConfig) TTL() time.Duration {
|
||
return c.Valid
|
||
}
|
||
|
||
// Validate 验证 Resolver 配置。
|
||
//
|
||
// 检查 DNS 服务器地址格式、TTL 和超时设置的有效性。
|
||
//
|
||
// 返回值:
|
||
// - error: 验证失败时的错误信息
|
||
func (c *ResolverConfig) Validate() error {
|
||
if !c.Enabled {
|
||
return nil
|
||
}
|
||
|
||
if len(c.Addresses) == 0 {
|
||
return errors.New("resolver.addresses is required when enabled")
|
||
}
|
||
|
||
for _, addr := range c.Addresses {
|
||
if _, err := net.ResolveUDPAddr("udp", addr); err != nil {
|
||
return fmt.Errorf("invalid DNS address %s: %w", addr, err)
|
||
}
|
||
}
|
||
|
||
if c.Valid > 0 && c.Valid < time.Second {
|
||
return errors.New("resolver.valid must be at least 1s")
|
||
}
|
||
|
||
if c.Timeout > 0 && c.Timeout < time.Second {
|
||
return errors.New("resolver.timeout must be at least 1s")
|
||
}
|
||
|
||
if !c.IPv4 && !c.IPv6 {
|
||
return errors.New("at least one of ipv4 or ipv6 must be enabled")
|
||
}
|
||
|
||
return nil
|
||
}
|