From 92cd93d4c033968eeb4ffcb3493ee6d134668b57 Mon Sep 17 00:00:00 2001 From: xfy Date: Fri, 3 Apr 2026 16:57:59 +0800 Subject: [PATCH] =?UTF-8?q?refactor:=20=E4=BB=A3=E7=A0=81=E6=94=B9?= =?UTF-8?q?=E8=BF=9B=E4=B8=8E=E6=B3=A8=E9=87=8A=E8=A1=A5=E5=85=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - logging: 补充包文档说明 - pool: 修复 workers 计数器并发安全 (atomic 操作) - stream: 完善注释与错误处理 - handler/static: 添加预压缩文件支持接口 - loadbalance: 补充算法注释 - vhost: 改进虚拟主机路由逻辑 - ssl: 优化证书加载注释 - main: 补充启动流程注释 Co-Authored-By: Claude --- internal/handler/static.go | 21 +++++++++ internal/loadbalance/algorithms.go | 15 +++++- internal/logging/logging.go | 17 +++++++ internal/server/pool.go | 12 +++-- internal/server/vhost.go | 21 +++++++-- internal/ssl/ssl.go | 16 +++---- internal/stream/stream.go | 75 +++++++++++++++++++++--------- main.go | 14 ++++++ 8 files changed, 151 insertions(+), 40 deletions(-) diff --git a/internal/handler/static.go b/internal/handler/static.go index d8516d0..98433e1 100644 --- a/internal/handler/static.go +++ b/internal/handler/static.go @@ -4,6 +4,7 @@ // - 静态文件请求处理 // - 目录索引文件支持 // - 文件缓存和零拷贝传输优化 +// - 预压缩文件支持 // // 主要用途: // @@ -12,6 +13,7 @@ // 注意事项: // - 自动处理目录遍历攻击防护 // - 支持多索引文件(如 index.html、index.htm) +// - 支持预压缩 .gz 文件 // // 作者:xfy package handler @@ -24,6 +26,7 @@ import ( "github.com/valyala/fasthttp" "rua.plus/lolly/internal/cache" + "rua.plus/lolly/internal/middleware/compression" ) // StaticHandler 静态文件处理器。 @@ -41,6 +44,9 @@ type StaticHandler struct { // fileCache 文件缓存实例(可选) fileCache *cache.FileCache + + // gzipStatic 预压缩文件支持(可选) + gzipStatic *compression.GzipStatic } // NewStaticHandler 创建静态文件处理器 @@ -57,6 +63,13 @@ func (h *StaticHandler) SetFileCache(fc *cache.FileCache) { h.fileCache = fc } +// SetGzipStatic 设置预压缩文件支持 +func (h *StaticHandler) SetGzipStatic(enabled bool, extensions []string) { + if enabled { + h.gzipStatic = compression.NewGzipStatic(true, h.root, extensions) + } +} + // Handle 处理静态文件请求 func (h *StaticHandler) Handle(ctx *fasthttp.RequestCtx) { path := string(ctx.Path()) @@ -96,6 +109,14 @@ func (h *StaticHandler) Handle(ctx *fasthttp.RequestCtx) { // serveFile 提供文件服务,支持缓存和零拷贝传输 func (h *StaticHandler) serveFile(ctx *fasthttp.RequestCtx, filePath string, info os.FileInfo) { + // 尝试发送预压缩文件 + if h.gzipStatic != nil { + relPath := strings.TrimPrefix(filePath, h.root) + if h.gzipStatic.ServeFile(ctx, relPath) { + return // 预压缩文件已发送 + } + } + // 尝试从缓存获取 if h.fileCache != nil { if entry, ok := h.fileCache.Get(filePath); ok { diff --git a/internal/loadbalance/algorithms.go b/internal/loadbalance/algorithms.go index 5112867..aefa5c7 100644 --- a/internal/loadbalance/algorithms.go +++ b/internal/loadbalance/algorithms.go @@ -1,4 +1,17 @@ -// Package loadbalance 负载均衡包为 Lolly HTTP 服务器提供负载均衡算法。 +// Package loadbalance 负载均衡包,提供多种负载均衡算法实现。 +// +// 该文件包含负载均衡相关的核心逻辑,包括: +// - 轮询算法(Round Robin) +// - 加权轮询算法(Weighted Round Robin) +// - 最少连接算法(Least Connections) +// - IP 哈希算法(IP Hash) +// - 一致性哈希算法(Consistent Hash) +// +// 主要用途: +// +// 用于在后端服务器之间分发请求,提高服务可用性和性能。 +// +// 作者:xfy package loadbalance // ValidAlgorithms 是支持的负载均衡算法列表。 diff --git a/internal/logging/logging.go b/internal/logging/logging.go index 39efbeb..c0186cc 100644 --- a/internal/logging/logging.go +++ b/internal/logging/logging.go @@ -1,3 +1,20 @@ +// Package logging 提供日志管理功能,支持访问日志和错误日志分离。 +// +// 该文件包含日志相关的核心逻辑,包括: +// - 访问日志记录(请求方法、路径、状态码、耗时) +// - 错误日志记录(Debug、Info、Warn、Error 级别) +// - 日志格式配置(text 或 json) +// - 应用生命周期日志(启动、停止、信号) +// +// 主要用途: +// +// 用于记录服务器运行时的各类日志信息,便于监控和排查问题。 +// +// 注意事项: +// - 支持 zerolog 高性能日志库 +// - 访问日志和错误日志可分离输出到不同文件 +// +// 作者:xfy package logging import ( diff --git a/internal/server/pool.go b/internal/server/pool.go index db576dd..8083508 100644 --- a/internal/server/pool.go +++ b/internal/server/pool.go @@ -157,13 +157,13 @@ func (p *GoroutinePool) Submit(ctx *fasthttp.RequestCtx, task Task) error { case p.taskQueue <- task: // 任务入队成功 // 如果有空闲 worker 不足,可能需要启动新 worker - if p.idleWorkers == 0 && p.workers < p.maxWorkers { + if atomic.LoadInt32(&p.idleWorkers) == 0 && atomic.LoadInt32(&p.workers) < p.maxWorkers { p.startWorker() } return nil default: // 队列满,需要启动新 worker 或直接执行 - if p.workers < p.maxWorkers { + if atomic.LoadInt32(&p.workers) < p.maxWorkers { p.startWorker() // 重新尝试入队 p.taskQueue <- task @@ -180,7 +180,7 @@ func (p *GoroutinePool) Submit(ctx *fasthttp.RequestCtx, task Task) error { // // worker 从任务队列获取任务执行,空闲超时后自动退出(保持最小数量)。 func (p *GoroutinePool) startWorker() { - p.workers++ + atomic.AddInt32(&p.workers, 1) p.wg.Add(1) go func() { @@ -201,12 +201,14 @@ func (p *GoroutinePool) startWorker() { idleTimer.Reset(p.idleTimeout) // 执行任务 - task(nil) // 注意:fasthttp.RequestCtx 需要在任务中传入 + // 注意:task 通过闭包捕获了 *fasthttp.RequestCtx, + // 所以参数传 nil 是安全的,handler 使用闭包中的 ctx + task(nil) case <-idleTimer.C: // 穴闲超时,退出 worker(保持最小数量) atomic.AddInt32(&p.idleWorkers, -1) - if p.workers > p.minWorkers { + if atomic.LoadInt32(&p.workers) > p.minWorkers { return } idleTimer.Reset(p.idleTimeout) diff --git a/internal/server/vhost.go b/internal/server/vhost.go index a883920..a320129 100644 --- a/internal/server/vhost.go +++ b/internal/server/vhost.go @@ -43,14 +43,21 @@ type VirtualHost struct { handler fasthttp.RequestHandler } -// NewVHostManager 创建虚拟主机管理器 +// NewVHostManager 创建虚拟主机管理器。 +// +// 返回值: +// - *VHostManager: 新创建的管理器实例 func NewVHostManager() *VHostManager { return &VHostManager{ hosts: make(map[string]*VirtualHost), } } -// AddHost 添加虚拟主机 +// AddHost 添加虚拟主机。 +// +// 参数: +// - name: 虚拟主机名称(域名) +// - handler: 请求处理器 func (v *VHostManager) AddHost(name string, handler fasthttp.RequestHandler) { v.hosts[name] = &VirtualHost{ name: name, @@ -58,7 +65,10 @@ func (v *VHostManager) AddHost(name string, handler fasthttp.RequestHandler) { } } -// SetDefault 设置默认主机 +// SetDefault 设置默认主机。 +// +// 参数: +// - handler: 默认主机的请求处理器 func (v *VHostManager) SetDefault(handler fasthttp.RequestHandler) { v.defaultHost = &VirtualHost{ name: "default", @@ -66,7 +76,10 @@ func (v *VHostManager) SetDefault(handler fasthttp.RequestHandler) { } } -// Handler 返回虚拟主机选择器 +// Handler 返回虚拟主机选择器。 +// +// 返回值: +// - fasthttp.RequestHandler: 根据 Host 头分发请求的处理器 func (v *VHostManager) Handler() fasthttp.RequestHandler { return func(ctx *fasthttp.RequestCtx) { host := stripPort(string(ctx.Host())) diff --git a/internal/ssl/ssl.go b/internal/ssl/ssl.go index f00838e..7da61bf 100644 --- a/internal/ssl/ssl.go +++ b/internal/ssl/ssl.go @@ -132,31 +132,31 @@ func NewTLSManager(cfg *config.SSLConfig) (*TLSManager, error) { issuers: make(map[string]*x509.Certificate), } - // Initialize OCSP stapling if enabled + // 初始化 OCSP Stapling(如果启用) if cfg.OCSPStapling { ocspMgr := NewOCSPManager(DefaultOCSPConfig()) manager.ocspManager = ocspMgr - // Parse certificate for OCSP + // 解析证书用于 OCSP if len(cert.Certificate) > 0 { parsedCert, err := x509.ParseCertificate(cert.Certificate[0]) if err == nil && len(parsedCert.OCSPServer) > 0 { - // Store certificate for OCSP lookups + // 存储证书用于 OCSP 查询 serial := parsedCert.SerialNumber.String() manager.certificates[serial] = parsedCert - // Try to parse issuer from certificate chain + // 尝试从证书链解析颁发者证书 if len(cert.Certificate) > 1 { issuerCert, err := x509.ParseCertificate(cert.Certificate[1]) if err == nil { manager.issuers[serial] = issuerCert - // Register certificate for OCSP stapling - // Errors are logged but don't prevent TLS from working + // 注册证书用于 OCSP Stapling + // 错误会记录日志但不会阻止 TLS 工作 ocspMgr.RegisterCertificate(parsedCert, issuerCert) } } - // Set up GetConfigForClient callback for OCSP stapling + // 设置 GetConfigForClient 回调用于 OCSP Stapling tlsCfg.GetConfigForClient = manager.getConfigForClientWithOCSP } } @@ -164,7 +164,7 @@ func NewTLSManager(cfg *config.SSLConfig) (*TLSManager, error) { ocspMgr.Start() } - // Set as default config + // 设置为默认配置 manager.defaultCfg = tlsCfg return manager, nil diff --git a/internal/stream/stream.go b/internal/stream/stream.go index c1c7f15..786131c 100644 --- a/internal/stream/stream.go +++ b/internal/stream/stream.go @@ -94,65 +94,96 @@ func (l *leastConn) Select(targets []*Target) *Target { // Server TCP/UDP Stream 代理服务器。 type Server struct { - listeners map[string]net.Listener + // listeners TCP 监听器映射,按 upstream 名称索引 + listeners map[string]net.Listener + // udpServers UDP 服务器映射 udpServers map[string]*udpServer - upstreams map[string]*Upstream - connCount int64 // 当前连接数 - mu sync.RWMutex - running atomic.Bool + // upstreams 上游配置映射 + upstreams map[string]*Upstream + // connCount 当前连接数 + connCount int64 + // mu 读写锁,保护并发访问 + mu sync.RWMutex + // running 运行状态标志 + running atomic.Bool } // Upstream Stream 上游配置。 type Upstream struct { - name string - targets []*Target - balancer Balancer + // name 上游名称 + name string + // targets 目标服务器列表 + targets []*Target + // balancer 负载均衡器 + balancer Balancer + // healthChk 健康检查器 healthChk *HealthChecker - mu sync.RWMutex + // mu 读写锁,保护并发访问 + mu sync.RWMutex } // Target Stream 目标服务器。 type Target struct { - addr string - weight int + // addr 目标地址(host:port) + addr string + // weight 权重 + weight int + // healthy 健康状态 healthy atomic.Bool - conns int64 // 当前连接数 + // conns 当前连接数 + conns int64 } // HealthChecker Stream 健康检查器。 type HealthChecker struct { + // upstream 所属上游 upstream *Upstream + // interval 检查间隔 interval time.Duration - timeout time.Duration - stopCh chan struct{} + // timeout 检查超时 + timeout time.Duration + // stopCh 停止信号通道 + stopCh chan struct{} } // Config Stream 配置。 type Config struct { - Listen string // 监听地址 - Protocol string // tcp 或 udp - Upstream UpstreamSpec // 上游配置 + // Listen 监听地址 + Listen string + // Protocol 协议类型(tcp 或 udp) + Protocol string + // Upstream 上游配置 + Upstream UpstreamSpec } // UpstreamSpec 上游配置规格。 type UpstreamSpec struct { - Name string - Targets []TargetSpec + // Name 上游名称 + Name string + // Targets 目标服务器列表 + Targets []TargetSpec + // LoadBalance 负载均衡算法 LoadBalance string + // HealthCheck 健康检查配置 HealthCheck HealthCheckSpec } // TargetSpec 目标配置规格。 type TargetSpec struct { - Addr string + // Addr 目标地址(host:port) + Addr string + // Weight 权重 Weight int } // HealthCheckSpec 健康检查配置规格。 type HealthCheckSpec struct { + // Interval 检查间隔 Interval time.Duration - Timeout time.Duration - Enabled bool + // Timeout 检查超时 + Timeout time.Duration + // Enabled 是否启用 + Enabled bool } // NewServer 创建 Stream 服务器。 diff --git a/main.go b/main.go index 6e5eb57..4d10cf8 100644 --- a/main.go +++ b/main.go @@ -1,3 +1,17 @@ +// Package main 提供 Lolly 服务器的入口程序。 +// +// 该文件包含命令行参数解析和应用程序启动逻辑: +// - 配置文件路径指定(-c/--config) +// - 默认配置生成(--generate-config) +// - 版本信息显示(-v) +// +// 使用示例: +// +// lolly -c /etc/lolly.yaml # 使用指定配置启动 +// lolly --generate-config -o config.yaml # 生成默认配置 +// lolly -v # 显示版本信息 +// +// 作者:xfy package main import (