refactor: 代码改进与注释补充

- logging: 补充包文档说明
- pool: 修复 workers 计数器并发安全 (atomic 操作)
- stream: 完善注释与错误处理
- handler/static: 添加预压缩文件支持接口
- loadbalance: 补充算法注释
- vhost: 改进虚拟主机路由逻辑
- ssl: 优化证书加载注释
- main: 补充启动流程注释

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
xfy 2026-04-03 16:57:59 +08:00
parent 03b0df2c69
commit 92cd93d4c0
8 changed files with 151 additions and 40 deletions

View File

@ -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 {

View File

@ -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 是支持的负载均衡算法列表。

View File

@ -1,3 +1,20 @@
// Package logging 提供日志管理功能,支持访问日志和错误日志分离。
//
// 该文件包含日志相关的核心逻辑,包括:
// - 访问日志记录(请求方法、路径、状态码、耗时)
// - 错误日志记录Debug、Info、Warn、Error 级别)
// - 日志格式配置text 或 json
// - 应用生命周期日志(启动、停止、信号)
//
// 主要用途:
//
// 用于记录服务器运行时的各类日志信息,便于监控和排查问题。
//
// 注意事项:
// - 支持 zerolog 高性能日志库
// - 访问日志和错误日志可分离输出到不同文件
//
// 作者xfy
package logging
import (

View File

@ -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)

View File

@ -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()))

View File

@ -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

View File

@ -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 服务器。

14
main.go
View File

@ -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 (