# Lolly 实现计划 ## 概述 **目标**:创建一个类似 nginx 的高性能 HTTP 服务器,纯 Go 实现,YAML 配置,单二进制运行。 **核心原则**: - 不是 1:1 复刻 nginx,而是更现代、更易用 - 充分利用 Go 特性(goroutine、channel、标准库) - 功能完整性优先于极致性能 - 选择"更简单易用"的设计方案 --- ## 第一阶段:项目骨架与配置系统 ### 目标 搭建项目基础结构,实现配置解析和命令行工具。 ### 任务列表 #### 1.1 项目目录结构 ``` lolly/ ├── cmd/lolly/main.go # 程序入口 ├── internal/ │ ├── config/ # 配置解析模块 │ ├── server/ # HTTP 服务器核心 │ ├── handler/ # 请求处理器 │ ├── middleware/ # 中间件系统(框架) │ │ ├── security/ # 安全中间件(access、ratelimit、auth) │ │ ├── compression/ # 压缩中间件(gzip、brotli) │ │ ├── logging/ # 日志中间件 │ │ └── rewrite/ # URL 重写中间件 │ ├── proxy/ # 反向代理模块 │ ├── loadbalance/ # 负载均衡模块 │ ├── ssl/ # SSL/TLS 模块 │ ├── cache/ # 缓存模块 │ ├── stream/ # TCP/UDP Stream 代理 │ └── logging/ # 日志系统核心 ├── pkg/ │ └── utils/ # 公共工具函数 ├── configs/ │ └── lolly.yaml # 默认配置示例 ├── go.mod ├── go.sum ├── Makefile # 构建脚本 └── README.md ``` **关键文件**: - `cmd/lolly/main.go` - 入口点,初始化和启动逻辑 - `internal/config/config.go` - 配置结构体定义和解析 - `internal/middleware/middleware.go` - 中间件框架接口定义 #### 1.2 YAML 配置解析 **配置结构体设计**: ```go // internal/config/config.go // Config 根配置结构 type Config struct { DefaultServer ServerConfig `yaml:"server"` // 默认服务器配置(单服务器场景) Servers []ServerConfig `yaml:"servers"` // 多虚拟主机配置(可选) Logging LoggingConfig `yaml:"logging"` Performance PerformanceConfig `yaml:"performance"` } // 配置字段语义说明: // - 若只配置 `server` 字段,则作为单一服务器运行 // - 若配置 `servers` 字段,则按虚拟主机模式运行(按 Host 头匹配) // - 若同时配置两者,`server` 作为默认 fallback 主机,`servers` 按名称匹配 // - 建议使用场景:简单部署用 `server`,多站点部署用 `servers` // ServerConfig 服务器配置 type ServerConfig struct { Listen string `yaml:"listen"` // 监听地址 ":8080" Name string `yaml:"name"` // server_name Static StaticConfig `yaml:"static"` // 静态文件 Proxy []ProxyConfig `yaml:"proxy"` // 反向代理规则 SSL SSLConfig `yaml:"ssl"` // SSL 配置 } // StaticConfig 静态文件配置 type StaticConfig struct { Root string `yaml:"root"` // 根目录 Index []string `yaml:"index"` // 索引文件 } // ProxyConfig 反向代理配置 type ProxyConfig struct { Path string `yaml:"path"` // 路径匹配 Target string `yaml:"target"` // 目标地址 LoadBalance string `yaml:"load_balance"` // 负载均衡算法 } ``` **实现要点**: - 使用 `gopkg.in/yaml.v3` 解析 YAML - 支持配置文件路径命令行参数 `-c/--config` - 配置验证:必填字段检查、路径有效性 - 默认配置:最小配置即可运行 #### 1.3 命令行工具 **支持的命令**: ```bash lolly # 启动服务器(默认配置) lolly -c /path/to.yaml # 指定配置文件 lolly -t # 测试配置语法 lolly -v # 显示版本 lolly -s reload # 重载配置(信号) lolly -s stop # 停止服务 lolly -s quit # 优雅停止 ``` **实现方式**: - 使用 `flag` 标准库处理参数 - 信号处理:`SIGTERM`、`SIGINT`、`SIGHUP` ### 验证方法 ```bash # 构建测试 go build -o lolly cmd/lolly/main.go # 配置解析测试 ./lolly -t -c configs/lolly.yaml # 输出:配置有效 # 版本显示 ./lolly -v # 输出:lolly version 0.1.0 ``` ### 提交信息 ``` feat(config): 实现项目骨架和 YAML 配置解析 - 创建项目目录结构(cmd/internal/pkg/configs) - 定义配置结构体(Server、Static、Proxy、Logging) - 实现 YAML 配置文件解析 - 添加命令行参数支持(-c、-t、-v、-s) - 添加默认配置示例文件 ``` --- ## 第二阶段:HTTP 核心功能 ### 目标 实现基础 HTTP 服务器、静态文件服务、请求路由、基础日志系统。 ### 任务列表 #### 2.0 中间件框架(前置依赖) **实现**: ```go // internal/middleware/middleware.go // Middleware 中间件接口 type Middleware interface { Name() string Process(next http.Handler) http.Handler } // Chain 中间件链 type Chain struct { middlewares []Middleware } // Apply 应用中间件链 func (c *Chain) Apply(final http.Handler) http.Handler ``` **设计要点**: - 定义统一的中间件接口,所有中间件(security、compression、logging 等)实现此接口 - 支持链式组合,按注册顺序执行 - Phase 1 建立框架,后续阶段填充具体中间件实现 #### 2.1 基础 HTTP 服务器 **核心实现**: ```go // internal/server/server.go // Server HTTP 服务器 type Server struct { config *config.Config handler *handler.Handler listeners map[string]*net.Listener running bool stopChan chan struct{} } // Start 启动服务器 func (s *Server) Start() error // Stop 停止服务器 func (s *Server) Stop() error // GracefulStop 优雅停止(等待请求完成) func (s *Server) GracefulStop(timeout time.Duration) error ``` **实现要点**: - 使用 `net/http` 标准库为基础 - 支持 multiple listeners(多端口/多虚拟主机) - 优雅关闭:`Shutdown()` 方法 - keep-alive 配置:`ReadTimeout`、`WriteTimeout`、`IdleTimeout` #### 2.2 静态文件服务 **实现**: ```go // internal/handler/static.go // StaticHandler 静态文件处理器 type StaticHandler struct { root string index []string } // ServeHTTP 处理静态文件请求 func (h *StaticHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) ``` **功能清单**: - 文件路径安全检查(防止目录遍历) - MIME 类型自动识别(`mime.TypeByExtension`) - 索引文件支持(index.html、index.htm) - 目录列表(可选,默认禁用) - Range 请求支持(部分下载) - 文件缓存优化(可选) #### 2.3 请求路由(Location 匹配) **路由设计**: ```go // internal/handler/router.go // Router 请求路由器 type Router struct { routes []*Route } // Route 路由规则 type Route struct { Path string // 路径模式 Type MatchType // 匹配类型:精确/前缀/正则 Handler http.Handler } // 匹配类型 type MatchType int const ( MatchExact MatchType = iota // 精确匹配 (=) MatchPrefix // 前缀匹配 (^~) MatchRegex // 正则匹配 (~) ) ``` **匹配优先级**(同 nginx): 1. 精确匹配 `=` 2. 前缀匹配(优先)`^~` 3. 正则匹配 `~`(按顺序) 4. 最长前缀匹配 #### 2.4 多虚拟主机支持 **实现**: ```go // internal/server/vhost.go // VHostManager 虚拟主机管理器 type VHostManager struct { hosts map[string]*VirtualHost // 按 server_name 索引 } ``` **功能**: - 按 `Host` 头选择虚拟主机 - 默认主机fallback - SNI 支持(SSL) #### 2.5 基础日志系统(Phase 2 必需) **原因**:调试 Phase 2-4 功能需要日志支持,将日志系统基础版本提前实现。 **实现**: ```go // internal/logging/logging.go // Logger 日志管理器 type Logger struct { level LogLevel output io.Writer } // LogLevel 日志级别 type LogLevel int const ( LogLevelDebug LogLevel = iota LogLevelInfo LogLevelWarn LogLevelError ) // AccessLogger 访问日志(基础版) func LogAccess(r *http.Request, status int, size int64, duration time.Duration) ``` **Phase 2 实现范围**: - 基础请求日志:记录请求方法、路径、状态码 - 控制台输出:开发阶段便于调试 - Phase 5 将扩展为完整日志系统(文件输出、自定义格式) ### 验证方法 ```bash # 启动服务器 ./lolly -c configs/lolly.yaml # 静态文件测试 curl http://localhost:8080/index.html # 路由测试 curl http://localhost:8080/static/test.txt curl http://localhost:8080/api/health # 应返回 404(代理未实现) ``` ### 提交信息 ``` feat(server): 实现 HTTP 服务器核心功能 - 实现中间件框架(Middleware 接口、Chain 链式组合) - 实现基础 HTTP 服务器(启动/停止/优雅关闭) - 实现静态文件服务(MIME 类型、索引文件、Range 请求) - 实现请求路由器(精确/前缀/正则匹配) - 支持多虚拟主机配置 - 支持 keep-alive 长连接配置 - 实现基础日志系统(控制台输出、请求日志) ``` --- ## 第三阶段:反向代理与负载均衡 ### 目标 实现反向代理功能、多种负载均衡算法、健康检查。 ### 任务列表 #### 3.1 反向代理核心 **实现**: ```go // internal/proxy/proxy.go // Proxy 反向代理 type Proxy struct { targets []*Target transport *http.Transport bufferPool *bufferPool } // Target 后端目标 type Target struct { URL *url.URL Weight int Healthy bool Connections int } ``` **功能清单**: - 请求转发:修改请求头、请求体 - 响应处理:修改响应头 - 超时配置:连接超时、响应超时 - WebSocket 支持:Upgrade 协议检测和转发 - 错误处理:后端不可用时的响应 #### 3.2 负载均衡算法 **实现**: ```go // internal/loadbalance/balancer.go // Balancer 负载均衡器接口 type Balancer interface { Select(targets []*Target) *Target } // RoundRobin 轮询算法 type RoundRobin struct { current uint64 } // WeightedRoundRobin 权重轮询 type WeightedRoundRobin struct { weights []int current int } // LeastConnections 最少连接 type LeastConnections struct{} // IPHash IP 哈希 type IPHash struct{} ``` **算法实现**: | 算法 | 说明 | |------|------| | round_robin | 简单轮询 | | weighted_round_robin | 按权重轮询 | | least_conn | 选择连接数最少的目标 | | ip_hash | 按客户端 IP 哈希固定目标 | #### 3.3 健康检查 **实现**: ```go // internal/proxy/health.go // HealthChecker 健康检查器 type HealthChecker struct { interval time.Duration timeout time.Duration path string // 健康检查路径 targets []*Target } // Check 执行健康检查 func (h *HealthChecker) Check() // Start 后台定期检查 func (h *HealthChecker) Start() ``` **类型**: - **被动检查**:请求失败时标记不健康 - **主动检查**:定期发送探测请求 **配置示例**: ```yaml 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 timeout: 5s ``` #### 3.4 代理缓存(可选) **实现**: ```go // internal/cache/proxy_cache.go // ProxyCache 代理响应缓存 type ProxyCache struct { storage CacheStorage rules []CacheRule } ``` ### 验证方法 ```bash # 启动后端服务(用于测试) # backend1: python3 -m http.server 8001 # backend2: python3 -m http.server 8002 # 配置代理 # lolly.yaml: # proxy: # - path: /api # targets: [http://localhost:8001, http://localhost:8002] # 测试代理 curl http://localhost:8080/api/test # 测试负载均衡(多次请求) for i in {1..10}; do curl http://localhost:8080/api/test; done ``` ### 提交信息 ``` feat(proxy): 实现反向代理和负载均衡功能 - 实现反向代理核心(请求转发、响应处理) - 实现负载均衡算法(轮询、权重、最少连接、IP哈希) - 实现被动健康检查(请求失败标记) - 实现主动健康检查(定期探测) - 支持 WebSocket 协议升级代理 ``` --- ## 第四阶段:安全与 SSL/TLS ### 目标 实现 HTTPS 支持、访问控制、请求限制。 ### 任务列表 #### 4.1 SSL/TLS 支持 **实现**: ```go // internal/ssl/ssl.go // SSLConfig SSL 配置 type SSLConfig struct { Cert string `yaml:"cert"` // 证书路径 Key string `yaml:"key"` // 私钥路径 CertChain string `yaml:"cert_chain"` // 证书链路径(可选,用于中间证书) Protocols []string `yaml:"protocols"` // TLS 版本,默认 ["TLSv1.2", "TLSv1.3"] Ciphers []string `yaml:"ciphers"` // 加密套件(仅 TLS 1.2 有效) OCSPStapling bool `yaml:"ocsp_stapling"` // OCSP Stapling 支持(默认 false) } // TLSManager TLS 管理器 type TLSManager struct { configs map[string]*tls.Config // 按 server_name } ``` **安全默认配置**: - **TLS 版本**:默认仅允许 TLSv1.2 和 TLSv1.3,**强制禁用 TLSv1.0/TLSv1.1** - **加密套件默认值**(TLS 1.2,按优先级排序): ```yaml # 默认安全加密套件,无需手动配置 ciphers: - TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 # 推荐,性能好 - TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 # 推荐,更安全 - TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305 # 推荐,移动端友好 - TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 # ECDSA 证书专用 - TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 # ECDSA 证书专用 - TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305 # ECDSA 证书专用 ``` - **TLS 1.3**:自动使用 Go 标准库的安全套件,配置无效 **安全校验**: - 启用 Basic Auth 时,**强制要求 SSL 配置**,否则拒绝启动 - 拒绝配置不安全的加密套件(如 RC4、DES、3DES) **功能清单**: - 证书加载:PEM 格式,支持证书链合并 - TLS 版本控制:TLSv1.2、TLSv1.3,**默认禁用不安全版本** - 加密套件配置:提供安全默认值,拒绝不安全套件 - SSL 会话缓存:减少握手开销(LRU 缓存,默认 128 条) - SNI 支持:多证书,通过 GetCertificate 回调实现 - HTTP/2 自动启用:TLS 时自动启用 - OCSP Stapling:减少客户端 CA 查询延迟和隐私风险 #### 4.2 IP 访问控制 **实现**: ```go // internal/middleware/security/access.go // AccessControl IP 访问控制 type AccessControl struct { allowList []net.IPNet denyList []net.IPNet default Action // 默认动作 } // Check 检查 IP 是否允许 func (a *AccessControl) Check(ip net.IP) bool ``` **性能优化建议**: - 使用 CIDR 树结构(radix tree)优化大规模 ACL 匹配 - 预编译匹配规则,减少运行时开销 - 支持 IPv4 和 IPv6 双栈匹配 **配置示例**: ```yaml security: access: allow: [192.168.1.0/24, 10.0.0.0/8, "2001:db8::/32"] # 支持 IPv6 deny: [192.168.2.100/32] default: deny # 可选:使用高性能匹配模式 optimize: true # 启用 CIDR 树优化(适用于 >100 条规则) ``` #### 4.3 请求限制 **实现**: ```go // internal/middleware/security/ratelimit.go // RateLimiter 速率限制器(令牌桶算法) type RateLimiter struct { rate int // 令牌生成速率(请求/秒) burst int // 桶容量(突发流量上限) buckets map[string]*TokenBucket mu sync.RWMutex } // TokenBucket 令牌桶 type TokenBucket struct { tokens float64 lastUpdate time.Time } // SlidingWindowLimiter 滑动窗口限流器(可选,解决边界突发问题) type SlidingWindowLimiter struct { window time.Duration limit int requests map[string][]time.Time } // ConnLimiter 连接数限制器 type ConnLimiter struct { max int current int mu sync.Mutex } ``` **算法选择**: | 算法 | 适用场景 | 特点 | |------|----------|------| | 令牌桶 (Token Bucket) | API 请求限流 | 允许突发流量,推荐默认使用 | | 滑动窗口 (Sliding Window) | 精确限流 | 解决固定窗口边界问题,无突发 | **功能**: - 请求速率限制(`limit_req`) - 连接数限制(`limit_conn`) - 按 IP 或按 key 限制 - 超限响应:429 Too Many Requests - 支持 `Retry-After` 响应头告知等待时间 #### 4.4 基础认证 **实现**: ```go // internal/middleware/security/auth.go // BasicAuth 基础认证 type BasicAuth struct { users map[string]string // username -> hashed_password algorithm HashAlgorithm // 哈希算法:bcrypt(默认)或 argon2id realm string requireTLS bool // 强制 HTTPS(默认 true) } // HashAlgorithm 哈希算法类型 type HashAlgorithm int const ( HashBcrypt HashAlgorithm = iota // bcrypt(默认,推荐) HashArgon2id // Argon2id(更安全,计算密集) ) // Authenticate 验证认证信息 func (b *BasicAuth) Authenticate(r *http.Request) bool ``` **安全要求**: - **强制 HTTPS**:启用 Basic Auth 时必须配置 SSL,否则拒绝启动 - **安全哈希**:默认使用 bcrypt(成本因子 12),可选 Argon2id - **弃用 apr1**:不再支持不安全的 MD5-based apr1 哈希 - **密码强度**:配置验证,拒绝弱密码 **配置示例**: ```yaml security: auth: type: basic require_tls: true # 强制 HTTPS(默认 true) algorithm: bcrypt # bcrypt(默认)或 argon2id users: - name: admin password: $2b$12$... # bcrypt 哈希(推荐) - name: api_user password: $argon2id$... # Argon2id 哈希(可选) realm: "Restricted Area" min_password_length: 12 # 密码最小长度 ``` #### 4.5 安全头部 **实现**: ```go // internal/middleware/security/headers.go // SecurityHeaders 安全头部配置 type SecurityHeaders struct { XFrameOptions string `yaml:"x_frame_options"` // DENY/SAMEORIGIN/ALLOW-FROM XContentTypeOptions string `yaml:"x_content_type_options"` // nosniff(默认) ContentSecurityPolicy string `yaml:"content_security_policy"` // CSP 策略 HSTS HSTSConfig `yaml:"hsts"` // HSTS 配置 ReferrerPolicy string `yaml:"referrer_policy"` // 推荐值 PermissionsPolicy string `yaml:"permissions_policy"` // 权限策略 } // HSTSConfig HSTS 配置 type HSTSConfig struct { MaxAge int `yaml:"max_age"` // 过期时间(秒),默认 31536000(1年) IncludeSubDomains bool `yaml:"include_sub_domains"` // 包含子域名,默认 true Preload bool `yaml:"preload"` // HSTS 预加载列表,默认 false } ``` **默认安全头部**: | 头部 | 默认值 | 说明 | |------|--------|------| | X-Frame-Options | DENY | 防止点击劫持,可配置为 SAMEORIGIN | | X-Content-Type-Options | nosniff | 防止 MIME 类型嗅探 | | Content-Security-Policy | 可配置 | **关键**:防止 XSS 攻击 | | Strict-Transport-Security | max-age=31536000; includeSubDomains | HSTS,强制 HTTPS | | Referrer-Policy | strict-origin-when-cross-origin | 控制引用信息泄露 | | Permissions-Policy | 可配置 | 控制浏览器功能权限 | **注意**:`X-XSS-Protection` 已被现代浏览器弃用,不再默认添加,重点依赖 CSP 防护。 **配置示例**: ```yaml security: headers: x_frame_options: SAMEORIGIN # 或 DENY(默认) content_security_policy: "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'" hsts: max_age: 31536000 # 1年 include_sub_domains: true # 包含子域名 preload: false # 不加入预加载列表(需用户显式启用) referrer_policy: strict-origin-when-cross-origin permissions_policy: "geolocation=(), microphone=(), camera=()" ``` ### 验证方法 ```bash # HTTPS 测试 curl -k https://localhost:8443/ # IP 访问控制测试 curl --interface 192.168.1.100 http://localhost:8080/ # 应允许 curl --interface 192.168.2.100 http://localhost:8080/ # 应拒绝 # 速率限制测试 for i in {1..20}; do curl http://localhost:8080/; done # 部分应返回 429 # 基础认证测试 curl -u admin:password http://localhost:8080/protected/ ``` ### 提交信息 ``` feat(security): 实现 SSL/TLS 和安全访问控制 - 实现 SSL/TLS 支持(证书加载、TLS版本、加密套件、OCSP Stapling) - 提供安全默认加密套件,强制禁用 TLSv1.0/TLSv1.1 - 实现 SSL 会话缓存和 SNI 多证书支持 - 实现 IP 访问控制(白名单/黑名单,支持 IPv6,CIDR 树优化) - 实现请求速率限制(令牌桶算法,支持滑动窗口) - 实现连接数限制 - 实现基础认证(bcrypt/Argon2id,强制 HTTPS) - 实现完整安全头部(CSP、HSTS、Referrer-Policy 等) ``` --- ## 第五阶段:增强功能 ### 目标 实现 URL 重写、压缩、缓存、日志系统。 ### 任务列表 #### 5.1 URL 重写 **实现**: ```go // internal/rewrite/rewrite.go // RewriteRule 重写规则 type RewriteRule struct { Pattern string // 匹配模式 Replacement string // 替换目标 Flag RewriteFlag // last/redirect/break } type RewriteFlag int const ( FlagLast RewriteFlag = iota // 继续匹配其他规则 FlagRedirect // 302 重定向 FlagPermanent // 301 重定向 FlagBreak // 停止匹配 ) ``` **配置示例**: ```yaml rewrite: - pattern: "^/old/(.*)$" replacement: "/new/$1" flag: permanent # 301 - pattern: "^/api/v1/(.*)$" replacement: "/api/v2/$1" flag: last ``` #### 5.2 Gzip/Brotli 压缩 **实现**: ```go // internal/compression/compression.go // CompressionHandler 压缩中间件 type CompressionHandler struct { types []string // 压缩的 MIME 类型 level int // 压缩级别 minSize int // 最小压缩大小 } ``` **配置示例**: ```yaml compression: type: gzip # gzip/brotli/both level: 6 # 1-9 min_size: 1024 # 最小 1KB 才压缩 types: [text/html, text/css, application/json] ``` #### 5.3 缓存系统 **静态文件缓存**: ```go // internal/cache/file_cache.go // FileCache 文件描述符缓存 type FileCache struct { maxEntries int maxSize int64 // 内存上限(新增) inactive time.Duration entries map[string]*FileEntry lruList *list.List // LRU 淘汰链表(新增) } // FileEntry 缓存条目 type FileEntry struct { fd *os.File size int64 modTime time.Time lastAccess time.Time } ``` **代理响应缓存**: ```go // internal/cache/proxy_cache.go // ProxyCache 代理缓存 type ProxyCache struct { storage Storage // 内存/磁盘存储 rules []CacheRule maxAge time.Duration cacheLock bool // 缓存锁开关(默认 true) lock *sync.RWMutex // 缓存锁,防止击穿 pending map[string]*chan struct{} // 正在生成的缓存项 } // CacheRule 缓存规则 type CacheRule struct { Path string Methods []string Statuses []int // 可缓存的响应状态码 MaxAge time.Duration } ``` **缓存锁机制(防击穿)**: - 当多个请求同时请求同一个未缓存的资源时,只让一个请求去后端获取 - 其他请求等待第一个请求完成后从缓存读取 - 防止缓存击穿导致后端压力骤增 **配置示例**: ```yaml cache: file: max_entries: 10000 max_size: 256MB # 内存上限 inactive: 20s lru_eviction: true # 启用 LRU 淘汰 proxy: enabled: true storage: memory # memory/disk max_size: 1GB cache_lock: true # 防止缓存击穿 stale_while_revalidate: 60s # 过期缓存复用 rules: - path: /api/cacheable methods: [GET] statuses: [200, 301, 302] max_age: 10m ``` #### 5.4 日志系统 **实现**: ```go // internal/logging/logging.go // Logger 日志管理器 type Logger struct { accessLog *AccessLogger errorLog *ErrorLogger level LogLevel } // AccessLogger 访问日志 type AccessLogger struct { format string // 日志格式 output io.Writer } // LogFormat 日志格式变量 // $remote_addr - 客户端 IP // $request - 请求行 // $status - 响应状态码 // $body_bytes_sent - 响应体大小 // $request_time - 请求耗时 ``` **配置示例**: ```yaml logging: access: path: /var/log/lolly/access.log format: "$remote_addr - $request - $status - $body_bytes_sent" error: path: /var/log/lolly/error.log level: info # debug/info/warn/error ``` #### 5.5 状态监控端点 **实现**: ```go // internal/server/status.go // StatusHandler 状态监控处理器 type StatusHandler struct { server *Server } // 返回数据 type Status struct { Connections int Requests int64 BytesSent int64 BytesReceived int64 Uptime time.Duration } ``` **配置示例**: ```yaml monitoring: status: path: /_status # 状态端点路径 allow: [127.0.0.1] # 仅允许本地访问 ``` ### 验证方法 ```bash # 重写测试 curl http://localhost:8080/old/page # 应重定向到 /new/page # 压缩测试 curl -H "Accept-Encoding: gzip" -I http://localhost:8080/index.html # 应返回 Content-Encoding: gzip # 缓存测试 curl -I http://localhost:8080/static/test.txt # 应返回缓存相关头部 # 日志测试 cat /var/log/lolly/access.log # 状态监控测试 curl http://localhost:8080/_status ``` ### 提交信息 ``` feat(enhance): 实现重写、压缩、缓存和日志功能 - 实现 URL 重写规则(正则匹配、301/302重定向) - 实现 Gzip 响应压缩 - 实现静态文件缓存(LRU 淘汰、内存上限控制) - 实现代理响应缓存(缓存锁防击穿) - 实现访问日志(可定制格式) - 实现分级错误日志 - 实现状态监控端点 ``` --- ## 第六阶段:高级功能 ### 目标 实现 TCP/UDP Stream 代理、性能优化、优雅升级。 ### 任务列表 #### 6.1 TCP/UDP Stream 代理 **实现**: ```go // internal/stream/stream.go // StreamServer TCP/UDP 代理服务器 type StreamServer struct { listeners map[string]*net.Listener upstreams map[string]*StreamUpstream } // StreamUpstream Stream 上游 type StreamUpstream struct { targets []*StreamTarget balancer Balancer } // StreamTarget Stream 目标 type StreamTarget struct { addr string healthy bool } ``` **配置示例**: ```yaml stream: - listen: 3306 protocol: tcp upstream: targets: [mysql1:3306, mysql2:3306] load_balance: round_robin - listen: 53 protocol: udp upstream: targets: [dns1:53, dns2:53] ``` #### 6.2 优雅升级(热升级) **实现**: ```go // internal/server/upgrade.go // GracefulUpgrade 优雅升级 func GracefulUpgrade(newBinary string) error // 逻辑: // 1. 启动新进程,继承监听 socket // 2. 新进程开始接受新连接 // 3. 旧进程停止接受新连接,完成现有请求后退出 ``` **信号处理**: - `SIGUSR2`:触发升级 - `SIGWINCH`:优雅关闭 worker #### 6.3 性能优化 **优化点**: ##### 6.3.1 连接复用 ```go // http.Transport 连接池配置 transport := &http.Transport{ MaxIdleConns: 100, // 最大空闲连接数 MaxIdleConnsPerHost: 32, // 每主机最大空闲连接 IdleConnTimeout: 90 * time.Second, // 空闲连接超时 MaxConnsPerHost: 0, // 每主机最大连接数(0=无限制) } ``` ##### 6.3.2 缓冲池 ```go // 使用 sync.Pool 实现分级缓冲池 var bufferPool = sync.Pool{ New: func() interface{} { return make([]byte, 32*1024) // 32KB 缓冲区 }, } ``` ##### 6.3.3 零拷贝(sendfile) ```go // internal/handler/sendfile.go // SendFile 零拷贝文件传输(仅 Linux) // 大文件(>= 8KB)使用 sendfile 系统调用 func SendFile(w http.ResponseWriter, f *os.File, offset, length int64) error { // Linux: syscall.Sendfile // macOS: syscall.Sendfile(不同签名) // Windows: syscall.TransmitFile // 其他平台: 降级为 io.Copy } // 跨平台兼容方案 // - Linux: sendfile(out_fd, in_fd, offset, count) // - macOS: sendfile(in_fd, out_fd, offset, &len, sf_hdtr, flags) // - Windows: TransmitFile(socket, handle, bytes_to_write, ... // - Fallback: io.CopyBuffer ``` ##### 6.3.4 Goroutine 池(可选) ```go // internal/server/pool.go // GoroutinePool Goroutine 池配置 type GoroutinePool struct { maxWorkers int // 最大 worker 数 minWorkers int // 最小 worker 数(预热) idleTimeout time.Duration // 空闲超时 taskQueue chan Task // 任务队列 } // 配置示例 performance: goroutine_pool: enabled: true // 启用池化(高 QPS 场景推荐) max_workers: 10000 // 最大并发数 min_workers: 100 // 预热 worker 数 idle_timeout: 60s // 空闲超时 ``` ##### 6.3.5 对象池 ```go // 使用 sync.Pool 复用对象 var requestPool = sync.Pool{ New: func() interface{} { return new(Request) }, } ``` ##### 6.3.6 代理缓存锁(防击穿) ```go // internal/cache/proxy_cache.go // ProxyCache 代理缓存(增加缓存锁) type ProxyCache struct { storage Storage rules []CacheRule maxAge time.Duration lock *sync.RWMutex // 缓存锁,防止缓存击穿 pending map[string]*chan struct{} // 正在生成的缓存项 } // 缓存锁机制: // 1. 请求到达时检查是否有 pending 请求 // 2. 有则等待 pending 完成 // 3. 无则创建 pending,生成缓存后广播 ``` #### 6.4 信号处理完善 **完整信号支持**: | 信号 | 行为 | |------|------| | `SIGTERM/SIGINT` | 快速停止 | | `SIGQUIT` | 优雅停止 | | `SIGHUP` | 重载配置 | | `SIGUSR1` | 重新打开日志 | | `SIGUSR2` | 热升级 | ### 验证方法 ```bash # TCP Stream 测试 # 启动 MySQL 后端 mysql -h localhost -P 3306 # 应通过 lolly 代理连接 # 热升级测试 kill -USR2 # 触发升级 ps aux | grep lolly # 应有两个进程 # 性能测试 # 使用 wrk 或 ab 进行压力测试 wrk -t4 -c1000 -d30s http://localhost:8080/ ``` ### 提交信息 ``` feat(advanced): 实现 Stream 代理和高级功能 - 实现 TCP Stream 代理和负载均衡 - 实现 UDP Stream 代理 - 实现优雅升级(热升级) - 完善信号处理(SIGHUP、SIGUSR1、SIGUSR2) - 实现性能优化: - 连接池复用(http.Transport 配置) - 分级缓冲池(sync.Pool) - 零拷贝 sendfile(跨平台兼容) - Goroutine 池(可选,高 QPS 场景) - 代理缓存锁(防止缓存击穿) ``` --- ## 文件依赖关系图 ``` Phase 1: cmd/lolly/main.go → internal/config/config.go cmd/lolly/main.go → internal/middleware/middleware.go Phase 2: internal/server/server.go → internal/config/config.go internal/server/server.go → internal/handler/router.go internal/server/server.go → internal/logging/logging.go internal/handler/router.go → internal/handler/static.go internal/handler/router.go → internal/middleware/middleware.go Phase 3: internal/handler/router.go → internal/proxy/proxy.go internal/proxy/proxy.go → internal/loadbalance/balancer.go internal/proxy/proxy.go → internal/proxy/health.go Phase 4: internal/server/server.go → internal/ssl/ssl.go internal/middleware/middleware.go → internal/middleware/security/access.go internal/middleware/middleware.go → internal/middleware/security/ratelimit.go internal/middleware/middleware.go → internal/middleware/security/auth.go internal/middleware/middleware.go → internal/middleware/security/headers.go Phase 5: internal/middleware/middleware.go → internal/middleware/rewrite/rewrite.go internal/middleware/middleware.go → internal/middleware/compression/compression.go internal/proxy/proxy.go → internal/cache/proxy_cache.go internal/server/server.go → internal/logging/logging.go(扩展) Phase 6: cmd/lolly/main.go → internal/stream/stream.go internal/server/server.go → internal/server/upgrade.go internal/server/server.go → internal/server/pool.go(可选) ``` --- ## 总体进度追踪 | 阶段 | 状态 | 主要功能 | |------|------|----------| | Phase 1 | 待开始 | 项目骨架、配置系统 | | Phase 2 | 待开始 | HTTP 核心、静态文件、路由 | | Phase 3 | 待开始 | 反向代理、负载均衡 | | Phase 4 | 待开始 | SSL/TLS、安全控制 | | Phase 5 | 待开始 | 重写、压缩、缓存、日志 | | Phase 6 | 待开始 | Stream、性能优化 | --- ## 参考文档 详细功能参考 `docs/` 目录: - HTTP 核心:`docs/03-nginx-http-core.md` - 代理负载均衡:`docs/04-nginx-proxy-loadbalancing.md` - SSL/HTTPS:`docs/05-nginx-ssl-https.md` - URL 重写:`docs/06-nginx-rewrite.md` - 压缩缓存:`docs/07-nginx-compression-caching.md` - 日志监控:`docs/08-nginx-logging-monitoring.md` - 安全控制:`docs/09-nginx-security.md` - Stream 代理:`docs/10-nginx-stream-tcp-udp.md` - 性能优化:`docs/12-nginx-performance-tuning.md` **代码注释规范**:`docs/comments.md`(必须遵循)