docs(plan): refine development plan with detailed implementation
- Add middleware framework as Phase 2 prerequisite - Move basic logging system to Phase 2 for debugging support - Add TLS security defaults (disable TLSv1.0/1.1, secure ciphers) - Expand security headers (CSP, HSTS, Referrer-Policy, Permissions-Policy) - Add cache lock mechanism to prevent cache stampede - Detail performance optimization (sendfile, goroutine pool, buffer pool) - Update dependency graph Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
9cae5ad8cf
commit
bdb774510f
447
docs/plan.md
447
docs/plan.md
@ -27,7 +27,17 @@ lolly/
|
||||
│ ├── config/ # 配置解析模块
|
||||
│ ├── server/ # HTTP 服务器核心
|
||||
│ ├── handler/ # 请求处理器
|
||||
│ └── middleware/ # 中间件系统
|
||||
│ ├── 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/
|
||||
@ -41,6 +51,7 @@ lolly/
|
||||
**关键文件**:
|
||||
- `cmd/lolly/main.go` - 入口点,初始化和启动逻辑
|
||||
- `internal/config/config.go` - 配置结构体定义和解析
|
||||
- `internal/middleware/middleware.go` - 中间件框架接口定义
|
||||
|
||||
#### 1.2 YAML 配置解析
|
||||
|
||||
@ -50,12 +61,18 @@ lolly/
|
||||
|
||||
// Config 根配置结构
|
||||
type Config struct {
|
||||
Server ServerConfig `yaml:"server"`
|
||||
Servers []ServerConfig `yaml:"servers"` // 多虚拟主机
|
||||
Logging LoggingConfig `yaml:"logging"`
|
||||
Performance PerformanceConfig `yaml:"performance"`
|
||||
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"
|
||||
@ -132,10 +149,36 @@ feat(config): 实现项目骨架和 YAML 配置解析
|
||||
## 第二阶段:HTTP 核心功能
|
||||
|
||||
### 目标
|
||||
实现基础 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 服务器
|
||||
|
||||
**核心实现**:
|
||||
@ -241,6 +284,38 @@ type VHostManager struct {
|
||||
- 默认主机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
|
||||
# 启动服务器
|
||||
@ -258,11 +333,13 @@ curl http://localhost:8080/api/health # 应返回 404(代理未实现)
|
||||
```
|
||||
feat(server): 实现 HTTP 服务器核心功能
|
||||
|
||||
- 实现中间件框架(Middleware 接口、Chain 链式组合)
|
||||
- 实现基础 HTTP 服务器(启动/停止/优雅关闭)
|
||||
- 实现静态文件服务(MIME 类型、索引文件、Range 请求)
|
||||
- 实现请求路由器(精确/前缀/正则匹配)
|
||||
- 支持多虚拟主机配置
|
||||
- 支持 keep-alive 长连接配置
|
||||
- 实现基础日志系统(控制台输出、请求日志)
|
||||
```
|
||||
|
||||
---
|
||||
@ -441,31 +518,53 @@ feat(proxy): 实现反向代理和负载均衡功能
|
||||
|
||||
// SSLConfig SSL 配置
|
||||
type SSLConfig struct {
|
||||
Cert string `yaml:"cert"` // 证书路径
|
||||
Key string `yaml:"key"` // 私钥路径
|
||||
Protocols []string `yaml:"protocols"` // TLS 版本
|
||||
Ciphers []string `yaml:"ciphers"` // 加密套件
|
||||
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
|
||||
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 会话缓存(减少握手开销)
|
||||
- SNI 支持(多证书)
|
||||
- HTTP/2 自动启用(TLS 时)
|
||||
- 证书加载:PEM 格式,支持证书链合并
|
||||
- TLS 版本控制:TLSv1.2、TLSv1.3,**默认禁用不安全版本**
|
||||
- 加密套件配置:提供安全默认值,拒绝不安全套件
|
||||
- SSL 会话缓存:减少握手开销(LRU 缓存,默认 128 条)
|
||||
- SNI 支持:多证书,通过 GetCertificate 回调实现
|
||||
- HTTP/2 自动启用:TLS 时自动启用
|
||||
- OCSP Stapling:减少客户端 CA 查询延迟和隐私风险
|
||||
|
||||
#### 4.2 IP 访问控制
|
||||
|
||||
**实现**:
|
||||
```go
|
||||
// internal/security/access.go
|
||||
// internal/middleware/security/access.go
|
||||
|
||||
// AccessControl IP 访问控制
|
||||
type AccessControl struct {
|
||||
@ -478,29 +577,49 @@ type AccessControl struct {
|
||||
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]
|
||||
deny: [192.168.2.100]
|
||||
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/security/ratelimit.go
|
||||
// internal/middleware/security/ratelimit.go
|
||||
|
||||
// RateLimiter 速率限制器
|
||||
// RateLimiter 速率限制器(令牌桶算法)
|
||||
type RateLimiter struct {
|
||||
requests int
|
||||
per time.Duration
|
||||
buckets map[string]*Bucket
|
||||
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
|
||||
@ -509,45 +628,115 @@ type ConnLimiter struct {
|
||||
}
|
||||
```
|
||||
|
||||
**算法选择**:
|
||||
| 算法 | 适用场景 | 特点 |
|
||||
|------|----------|------|
|
||||
| 令牌桶 (Token Bucket) | API 请求限流 | 允许突发流量,推荐默认使用 |
|
||||
| 滑动窗口 (Sliding Window) | 精确限流 | 解决固定窗口边界问题,无突发 |
|
||||
|
||||
**功能**:
|
||||
- 请求速率限制(`limit_req`)
|
||||
- 连接数限制(`limit_conn`)
|
||||
- 按 IP 或按 key 限制
|
||||
- 超限响应:429 Too Many Requests
|
||||
- 支持 `Retry-After` 响应头告知等待时间
|
||||
|
||||
#### 4.4 基础认证
|
||||
|
||||
**实现**:
|
||||
```go
|
||||
// internal/security/auth.go
|
||||
// internal/middleware/security/auth.go
|
||||
|
||||
// BasicAuth 基础认证
|
||||
type BasicAuth struct {
|
||||
users map[string]string // username -> hashed_password
|
||||
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: $apr1$... # htpasswd 格式
|
||||
password: $2b$12$... # bcrypt 哈希(推荐)
|
||||
- name: api_user
|
||||
password: $argon2id$... # Argon2id 哈希(可选)
|
||||
realm: "Restricted Area"
|
||||
min_password_length: 12 # 密码最小长度
|
||||
```
|
||||
|
||||
#### 4.5 安全头部
|
||||
|
||||
**自动添加的安全头**:
|
||||
- `X-Frame-Options: DENY`
|
||||
- `X-Content-Type-Options: nosniff`
|
||||
- `X-XSS-Protection: 1; mode=block`
|
||||
- `Strict-Transport-Security: max-age=31536000`
|
||||
**实现**:
|
||||
```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
|
||||
@ -569,14 +758,14 @@ curl -u admin:password http://localhost:8080/protected/
|
||||
```
|
||||
feat(security): 实现 SSL/TLS 和安全访问控制
|
||||
|
||||
- 实现 SSL/TLS 支持(证书加载、TLS版本、加密套件)
|
||||
- 实现 SSL 会话缓存
|
||||
- 实现 SNI 多证书支持
|
||||
- 实现 IP 访问控制(白名单/黑名单)
|
||||
- 实现请求速率限制
|
||||
- 实现 SSL/TLS 支持(证书加载、TLS版本、加密套件、OCSP Stapling)
|
||||
- 提供安全默认加密套件,强制禁用 TLSv1.0/TLSv1.1
|
||||
- 实现 SSL 会话缓存和 SNI 多证书支持
|
||||
- 实现 IP 访问控制(白名单/黑名单,支持 IPv6,CIDR 树优化)
|
||||
- 实现请求速率限制(令牌桶算法,支持滑动窗口)
|
||||
- 实现连接数限制
|
||||
- 实现基础认证(Basic Auth)
|
||||
- 添加安全响应头部
|
||||
- 实现基础认证(bcrypt/Argon2id,强制 HTTPS)
|
||||
- 实现完整安全头部(CSP、HSTS、Referrer-Policy 等)
|
||||
```
|
||||
|
||||
---
|
||||
@ -653,8 +842,18 @@ compression:
|
||||
// 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
|
||||
}
|
||||
```
|
||||
|
||||
@ -664,10 +863,48 @@ type FileCache struct {
|
||||
|
||||
// ProxyCache 代理缓存
|
||||
type ProxyCache struct {
|
||||
storage Storage // 内存/磁盘存储
|
||||
rules []CacheRule
|
||||
maxAge time.Duration
|
||||
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 日志系统
|
||||
@ -763,8 +1000,8 @@ feat(enhance): 实现重写、压缩、缓存和日志功能
|
||||
|
||||
- 实现 URL 重写规则(正则匹配、301/302重定向)
|
||||
- 实现 Gzip 响应压缩
|
||||
- 实现静态文件缓存(文件描述符缓存)
|
||||
- 实现代理响应缓存
|
||||
- 实现静态文件缓存(LRU 淘汰、内存上限控制)
|
||||
- 实现代理响应缓存(缓存锁防击穿)
|
||||
- 实现访问日志(可定制格式)
|
||||
- 实现分级错误日志
|
||||
- 实现状态监控端点
|
||||
@ -840,11 +1077,97 @@ func GracefulUpgrade(newBinary string) error
|
||||
#### 6.3 性能优化
|
||||
|
||||
**优化点**:
|
||||
- 连接复用:`http.Transport` 配置
|
||||
- 缓冲池:减少内存分配
|
||||
- 零拷贝:`io.Copy` 使用 `sendfile`(Linux)
|
||||
- Goroutine 池:控制并发数(可选)
|
||||
- 对象池:`sync.Pool` 复用对象
|
||||
|
||||
##### 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 信号处理完善
|
||||
|
||||
@ -880,7 +1203,12 @@ feat(advanced): 实现 Stream 代理和高级功能
|
||||
- 实现 UDP Stream 代理
|
||||
- 实现优雅升级(热升级)
|
||||
- 完善信号处理(SIGHUP、SIGUSR1、SIGUSR2)
|
||||
- 实现性能优化(连接复用、缓冲池)
|
||||
- 实现性能优化:
|
||||
- 连接池复用(http.Transport 配置)
|
||||
- 分级缓冲池(sync.Pool)
|
||||
- 零拷贝 sendfile(跨平台兼容)
|
||||
- Goroutine 池(可选,高 QPS 场景)
|
||||
- 代理缓存锁(防止缓存击穿)
|
||||
```
|
||||
|
||||
---
|
||||
@ -890,11 +1218,14 @@ feat(advanced): 实现 Stream 代理和高级功能
|
||||
```
|
||||
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
|
||||
@ -903,19 +1234,21 @@ Phase 3:
|
||||
|
||||
Phase 4:
|
||||
internal/server/server.go → internal/ssl/ssl.go
|
||||
internal/handler/router.go → internal/security/access.go
|
||||
internal/handler/router.go → internal/security/ratelimit.go
|
||||
internal/handler/router.go → internal/security/auth.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/handler/router.go → internal/rewrite/rewrite.go
|
||||
internal/server/server.go → internal/compression/compression.go
|
||||
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
|
||||
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(可选)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user