docs(plan): 格式化开发计划文档
- 调整列表格式和缩进 - 移除各阶段提交信息模板(冗余) - 简化项目目录结构描述 Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
0301061a52
commit
3fb259419b
242
docs/plan.md
242
docs/plan.md
@ -5,6 +5,7 @@
|
||||
**目标**:创建一个类似 nginx 的高性能 HTTP 服务器,纯 Go 实现,YAML 配置,单二进制运行。
|
||||
|
||||
**核心原则**:
|
||||
|
||||
- 不是 1:1 复刻 nginx,而是更现代、更易用
|
||||
- 充分利用 Go 特性(goroutine、channel、标准库)
|
||||
- 功能完整性优先于极致性能
|
||||
@ -15,14 +16,16 @@
|
||||
## 第一阶段:项目骨架与配置系统
|
||||
|
||||
### 目标
|
||||
|
||||
搭建项目基础结构,实现配置解析和命令行工具。
|
||||
|
||||
### 任务列表
|
||||
|
||||
#### 1.1 项目目录结构
|
||||
|
||||
```
|
||||
lolly/
|
||||
├── cmd/lolly/main.go # 程序入口
|
||||
├── main.go # 程序入口
|
||||
├── internal/
|
||||
│ ├── config/ # 配置解析模块
|
||||
│ ├── server/ # HTTP 服务器核心
|
||||
@ -40,8 +43,6 @@ lolly/
|
||||
│ └── logging/ # 日志系统核心
|
||||
├── pkg/
|
||||
│ └── utils/ # 公共工具函数
|
||||
├── configs/
|
||||
│ └── lolly.yaml # 默认配置示例
|
||||
├── go.mod
|
||||
├── go.sum
|
||||
├── Makefile # 构建脚本
|
||||
@ -49,13 +50,15 @@ lolly/
|
||||
```
|
||||
|
||||
**关键文件**:
|
||||
- `cmd/lolly/main.go` - 入口点,初始化和启动逻辑
|
||||
|
||||
- `main.go` - 入口点,初始化和启动逻辑
|
||||
- `internal/config/config.go` - 配置结构体定义和解析
|
||||
- `internal/middleware/middleware.go` - 中间件框架接口定义
|
||||
|
||||
#### 1.2 YAML 配置解析
|
||||
|
||||
**配置结构体设计**:
|
||||
|
||||
```go
|
||||
// internal/config/config.go
|
||||
|
||||
@ -97,6 +100,7 @@ type ProxyConfig struct {
|
||||
```
|
||||
|
||||
**实现要点**:
|
||||
|
||||
- 使用 `gopkg.in/yaml.v3` 解析 YAML
|
||||
- 支持配置文件路径命令行参数 `-c/--config`
|
||||
- 配置验证:必填字段检查、路径有效性
|
||||
@ -105,24 +109,23 @@ type ProxyConfig struct {
|
||||
#### 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
|
||||
make build
|
||||
|
||||
# 配置解析测试
|
||||
./lolly -t -c configs/lolly.yaml
|
||||
@ -130,18 +133,6 @@ go build -o lolly cmd/lolly/main.go
|
||||
|
||||
# 版本显示
|
||||
./lolly -v
|
||||
# 输出:lolly version 0.1.0
|
||||
```
|
||||
|
||||
### 提交信息
|
||||
```
|
||||
feat(config): 实现项目骨架和 YAML 配置解析
|
||||
|
||||
- 创建项目目录结构(cmd/internal/pkg/configs)
|
||||
- 定义配置结构体(Server、Static、Proxy、Logging)
|
||||
- 实现 YAML 配置文件解析
|
||||
- 添加命令行参数支持(-c、-t、-v、-s)
|
||||
- 添加默认配置示例文件
|
||||
```
|
||||
|
||||
---
|
||||
@ -149,6 +140,7 @@ feat(config): 实现项目骨架和 YAML 配置解析
|
||||
## 第二阶段:HTTP 核心功能
|
||||
|
||||
### 目标
|
||||
|
||||
实现基础 HTTP 服务器、静态文件服务、请求路由、基础日志系统。
|
||||
|
||||
### 任务列表
|
||||
@ -156,6 +148,7 @@ feat(config): 实现项目骨架和 YAML 配置解析
|
||||
#### 2.0 中间件框架(前置依赖)
|
||||
|
||||
**实现**:
|
||||
|
||||
```go
|
||||
// internal/middleware/middleware.go
|
||||
|
||||
@ -175,6 +168,7 @@ func (c *Chain) Apply(final http.Handler) http.Handler
|
||||
```
|
||||
|
||||
**设计要点**:
|
||||
|
||||
- 定义统一的中间件接口,所有中间件(security、compression、logging 等)实现此接口
|
||||
- 支持链式组合,按注册顺序执行
|
||||
- Phase 1 建立框架,后续阶段填充具体中间件实现
|
||||
@ -182,6 +176,7 @@ func (c *Chain) Apply(final http.Handler) http.Handler
|
||||
#### 2.1 基础 HTTP 服务器
|
||||
|
||||
**核心实现**:
|
||||
|
||||
```go
|
||||
// internal/server/server.go
|
||||
|
||||
@ -205,6 +200,7 @@ func (s *Server) GracefulStop(timeout time.Duration) error
|
||||
```
|
||||
|
||||
**实现要点**:
|
||||
|
||||
- 使用 `net/http` 标准库为基础
|
||||
- 支持 multiple listeners(多端口/多虚拟主机)
|
||||
- 优雅关闭:`Shutdown()` 方法
|
||||
@ -213,6 +209,7 @@ func (s *Server) GracefulStop(timeout time.Duration) error
|
||||
#### 2.2 静态文件服务
|
||||
|
||||
**实现**:
|
||||
|
||||
```go
|
||||
// internal/handler/static.go
|
||||
|
||||
@ -227,6 +224,7 @@ func (h *StaticHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)
|
||||
```
|
||||
|
||||
**功能清单**:
|
||||
|
||||
- 文件路径安全检查(防止目录遍历)
|
||||
- MIME 类型自动识别(`mime.TypeByExtension`)
|
||||
- 索引文件支持(index.html、index.htm)
|
||||
@ -237,6 +235,7 @@ func (h *StaticHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)
|
||||
#### 2.3 请求路由(Location 匹配)
|
||||
|
||||
**路由设计**:
|
||||
|
||||
```go
|
||||
// internal/handler/router.go
|
||||
|
||||
@ -262,6 +261,7 @@ const (
|
||||
```
|
||||
|
||||
**匹配优先级**(同 nginx):
|
||||
|
||||
1. 精确匹配 `=`
|
||||
2. 前缀匹配(优先)`^~`
|
||||
3. 正则匹配 `~`(按顺序)
|
||||
@ -270,6 +270,7 @@ const (
|
||||
#### 2.4 多虚拟主机支持
|
||||
|
||||
**实现**:
|
||||
|
||||
```go
|
||||
// internal/server/vhost.go
|
||||
|
||||
@ -280,6 +281,7 @@ type VHostManager struct {
|
||||
```
|
||||
|
||||
**功能**:
|
||||
|
||||
- 按 `Host` 头选择虚拟主机
|
||||
- 默认主机fallback
|
||||
- SNI 支持(SSL)
|
||||
@ -289,6 +291,7 @@ type VHostManager struct {
|
||||
**原因**:调试 Phase 2-4 功能需要日志支持,将日志系统基础版本提前实现。
|
||||
|
||||
**实现**:
|
||||
|
||||
```go
|
||||
// internal/logging/logging.go
|
||||
|
||||
@ -312,11 +315,13 @@ func LogAccess(r *http.Request, status int, size int64, duration time.Duration)
|
||||
```
|
||||
|
||||
**Phase 2 实现范围**:
|
||||
|
||||
- 基础请求日志:记录请求方法、路径、状态码
|
||||
- 控制台输出:开发阶段便于调试
|
||||
- Phase 5 将扩展为完整日志系统(文件输出、自定义格式)
|
||||
|
||||
### 验证方法
|
||||
|
||||
```bash
|
||||
# 启动服务器
|
||||
./lolly -c configs/lolly.yaml
|
||||
@ -329,24 +334,12 @@ curl http://localhost:8080/static/test.txt
|
||||
curl http://localhost:8080/api/health # 应返回 404(代理未实现)
|
||||
```
|
||||
|
||||
### 提交信息
|
||||
```
|
||||
feat(server): 实现 HTTP 服务器核心功能
|
||||
|
||||
- 实现中间件框架(Middleware 接口、Chain 链式组合)
|
||||
- 实现基础 HTTP 服务器(启动/停止/优雅关闭)
|
||||
- 实现静态文件服务(MIME 类型、索引文件、Range 请求)
|
||||
- 实现请求路由器(精确/前缀/正则匹配)
|
||||
- 支持多虚拟主机配置
|
||||
- 支持 keep-alive 长连接配置
|
||||
- 实现基础日志系统(控制台输出、请求日志)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 第三阶段:反向代理与负载均衡
|
||||
|
||||
### 目标
|
||||
|
||||
实现反向代理功能、多种负载均衡算法、健康检查。
|
||||
|
||||
### 任务列表
|
||||
@ -354,6 +347,7 @@ feat(server): 实现 HTTP 服务器核心功能
|
||||
#### 3.1 反向代理核心
|
||||
|
||||
**实现**:
|
||||
|
||||
```go
|
||||
// internal/proxy/proxy.go
|
||||
|
||||
@ -374,6 +368,7 @@ type Target struct {
|
||||
```
|
||||
|
||||
**功能清单**:
|
||||
|
||||
- 请求转发:修改请求头、请求体
|
||||
- 响应处理:修改响应头
|
||||
- 超时配置:连接超时、响应超时
|
||||
@ -383,6 +378,7 @@ type Target struct {
|
||||
#### 3.2 负载均衡算法
|
||||
|
||||
**实现**:
|
||||
|
||||
```go
|
||||
// internal/loadbalance/balancer.go
|
||||
|
||||
@ -420,6 +416,7 @@ type IPHash struct{}
|
||||
#### 3.3 健康检查
|
||||
|
||||
**实现**:
|
||||
|
||||
```go
|
||||
// internal/proxy/health.go
|
||||
|
||||
@ -439,10 +436,12 @@ func (h *HealthChecker) Start()
|
||||
```
|
||||
|
||||
**类型**:
|
||||
|
||||
- **被动检查**:请求失败时标记不健康
|
||||
- **主动检查**:定期发送探测请求
|
||||
|
||||
**配置示例**:
|
||||
|
||||
```yaml
|
||||
proxy:
|
||||
- path: /api
|
||||
@ -461,6 +460,7 @@ proxy:
|
||||
#### 3.4 代理缓存(可选)
|
||||
|
||||
**实现**:
|
||||
|
||||
```go
|
||||
// internal/cache/proxy_cache.go
|
||||
|
||||
@ -472,6 +472,7 @@ type ProxyCache struct {
|
||||
```
|
||||
|
||||
### 验证方法
|
||||
|
||||
```bash
|
||||
# 启动后端服务(用于测试)
|
||||
# backend1: python3 -m http.server 8001
|
||||
@ -490,22 +491,12 @@ 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 支持、访问控制、请求限制。
|
||||
|
||||
### 任务列表
|
||||
@ -513,6 +504,7 @@ feat(proxy): 实现反向代理和负载均衡功能
|
||||
#### 4.1 SSL/TLS 支持
|
||||
|
||||
**实现**:
|
||||
|
||||
```go
|
||||
// internal/ssl/ssl.go
|
||||
|
||||
@ -533,25 +525,28 @@ type TLSManager struct {
|
||||
```
|
||||
|
||||
**安全默认配置**:
|
||||
|
||||
- **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_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,**默认禁用不安全版本**
|
||||
- 加密套件配置:提供安全默认值,拒绝不安全套件
|
||||
@ -563,6 +558,7 @@ type TLSManager struct {
|
||||
#### 4.2 IP 访问控制
|
||||
|
||||
**实现**:
|
||||
|
||||
```go
|
||||
// internal/middleware/security/access.go
|
||||
|
||||
@ -578,24 +574,27 @@ 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
|
||||
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 条规则)
|
||||
optimize: true # 启用 CIDR 树优化(适用于 >100 条规则)
|
||||
```
|
||||
|
||||
#### 4.3 请求限制
|
||||
|
||||
**实现**:
|
||||
|
||||
```go
|
||||
// internal/middleware/security/ratelimit.go
|
||||
|
||||
@ -635,6 +634,7 @@ type ConnLimiter struct {
|
||||
| 滑动窗口 (Sliding Window) | 精确限流 | 解决固定窗口边界问题,无突发 |
|
||||
|
||||
**功能**:
|
||||
|
||||
- 请求速率限制(`limit_req`)
|
||||
- 连接数限制(`limit_conn`)
|
||||
- 按 IP 或按 key 限制
|
||||
@ -644,6 +644,7 @@ type ConnLimiter struct {
|
||||
#### 4.4 基础认证
|
||||
|
||||
**实现**:
|
||||
|
||||
```go
|
||||
// internal/middleware/security/auth.go
|
||||
|
||||
@ -667,30 +668,33 @@ 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
|
||||
require_tls: true # 强制 HTTPS(默认 true)
|
||||
algorithm: bcrypt # bcrypt(默认)或 argon2id
|
||||
users:
|
||||
- name: admin
|
||||
password: $2b$12$... # bcrypt 哈希(推荐)
|
||||
password: $2b$12$... # bcrypt 哈希(推荐)
|
||||
- name: api_user
|
||||
password: $argon2id$... # Argon2id 哈希(可选)
|
||||
password: $argon2id$... # Argon2id 哈希(可选)
|
||||
realm: "Restricted Area"
|
||||
min_password_length: 12 # 密码最小长度
|
||||
min_password_length: 12 # 密码最小长度
|
||||
```
|
||||
|
||||
#### 4.5 安全头部
|
||||
|
||||
**实现**:
|
||||
|
||||
```go
|
||||
// internal/middleware/security/headers.go
|
||||
|
||||
@ -725,20 +729,22 @@ type HSTSConfig struct {
|
||||
**注意**:`X-XSS-Protection` 已被现代浏览器弃用,不再默认添加,重点依赖 CSP 防护。
|
||||
|
||||
**配置示例**:
|
||||
|
||||
```yaml
|
||||
security:
|
||||
headers:
|
||||
x_frame_options: SAMEORIGIN # 或 DENY(默认)
|
||||
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 # 不加入预加载列表(需用户显式启用)
|
||||
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/
|
||||
@ -754,25 +760,12 @@ 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 重写、压缩、缓存、日志系统。
|
||||
|
||||
### 任务列表
|
||||
@ -780,6 +773,7 @@ feat(security): 实现 SSL/TLS 和安全访问控制
|
||||
#### 5.1 URL 重写
|
||||
|
||||
**实现**:
|
||||
|
||||
```go
|
||||
// internal/rewrite/rewrite.go
|
||||
|
||||
@ -800,11 +794,12 @@ const (
|
||||
```
|
||||
|
||||
**配置示例**:
|
||||
|
||||
```yaml
|
||||
rewrite:
|
||||
- pattern: "^/old/(.*)$"
|
||||
replacement: "/new/$1"
|
||||
flag: permanent # 301
|
||||
flag: permanent # 301
|
||||
- pattern: "^/api/v1/(.*)$"
|
||||
replacement: "/api/v2/$1"
|
||||
flag: last
|
||||
@ -813,6 +808,7 @@ rewrite:
|
||||
#### 5.2 Gzip/Brotli 压缩
|
||||
|
||||
**实现**:
|
||||
|
||||
```go
|
||||
// internal/compression/compression.go
|
||||
|
||||
@ -825,17 +821,19 @@ type CompressionHandler struct {
|
||||
```
|
||||
|
||||
**配置示例**:
|
||||
|
||||
```yaml
|
||||
compression:
|
||||
type: gzip # gzip/brotli/both
|
||||
level: 6 # 1-9
|
||||
min_size: 1024 # 最小 1KB 才压缩
|
||||
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
|
||||
|
||||
@ -858,6 +856,7 @@ type FileEntry struct {
|
||||
```
|
||||
|
||||
**代理响应缓存**:
|
||||
|
||||
```go
|
||||
// internal/cache/proxy_cache.go
|
||||
|
||||
@ -881,25 +880,27 @@ type CacheRule struct {
|
||||
```
|
||||
|
||||
**缓存锁机制(防击穿)**:
|
||||
|
||||
- 当多个请求同时请求同一个未缓存的资源时,只让一个请求去后端获取
|
||||
- 其他请求等待第一个请求完成后从缓存读取
|
||||
- 防止缓存击穿导致后端压力骤增
|
||||
|
||||
**配置示例**:
|
||||
|
||||
```yaml
|
||||
cache:
|
||||
file:
|
||||
max_entries: 10000
|
||||
max_size: 256MB # 内存上限
|
||||
max_size: 256MB # 内存上限
|
||||
inactive: 20s
|
||||
lru_eviction: true # 启用 LRU 淘汰
|
||||
|
||||
lru_eviction: true # 启用 LRU 淘汰
|
||||
|
||||
proxy:
|
||||
enabled: true
|
||||
storage: memory # memory/disk
|
||||
storage: memory # memory/disk
|
||||
max_size: 1GB
|
||||
cache_lock: true # 防止缓存击穿
|
||||
stale_while_revalidate: 60s # 过期缓存复用
|
||||
cache_lock: true # 防止缓存击穿
|
||||
stale_while_revalidate: 60s # 过期缓存复用
|
||||
rules:
|
||||
- path: /api/cacheable
|
||||
methods: [GET]
|
||||
@ -910,6 +911,7 @@ cache:
|
||||
#### 5.4 日志系统
|
||||
|
||||
**实现**:
|
||||
|
||||
```go
|
||||
// internal/logging/logging.go
|
||||
|
||||
@ -935,6 +937,7 @@ type AccessLogger struct {
|
||||
```
|
||||
|
||||
**配置示例**:
|
||||
|
||||
```yaml
|
||||
logging:
|
||||
access:
|
||||
@ -942,12 +945,13 @@ logging:
|
||||
format: "$remote_addr - $request - $status - $body_bytes_sent"
|
||||
error:
|
||||
path: /var/log/lolly/error.log
|
||||
level: info # debug/info/warn/error
|
||||
level: info # debug/info/warn/error
|
||||
```
|
||||
|
||||
#### 5.5 状态监控端点
|
||||
|
||||
**实现**:
|
||||
|
||||
```go
|
||||
// internal/server/status.go
|
||||
|
||||
@ -967,14 +971,16 @@ type Status struct {
|
||||
```
|
||||
|
||||
**配置示例**:
|
||||
|
||||
```yaml
|
||||
monitoring:
|
||||
status:
|
||||
path: /_status # 状态端点路径
|
||||
allow: [127.0.0.1] # 仅允许本地访问
|
||||
path: /_status # 状态端点路径
|
||||
allow: [127.0.0.1] # 仅允许本地访问
|
||||
```
|
||||
|
||||
### 验证方法
|
||||
|
||||
```bash
|
||||
# 重写测试
|
||||
curl http://localhost:8080/old/page # 应重定向到 /new/page
|
||||
@ -994,24 +1000,12 @@ cat /var/log/lolly/access.log
|
||||
curl http://localhost:8080/_status
|
||||
```
|
||||
|
||||
### 提交信息
|
||||
```
|
||||
feat(enhance): 实现重写、压缩、缓存和日志功能
|
||||
|
||||
- 实现 URL 重写规则(正则匹配、301/302重定向)
|
||||
- 实现 Gzip 响应压缩
|
||||
- 实现静态文件缓存(LRU 淘汰、内存上限控制)
|
||||
- 实现代理响应缓存(缓存锁防击穿)
|
||||
- 实现访问日志(可定制格式)
|
||||
- 实现分级错误日志
|
||||
- 实现状态监控端点
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 第六阶段:高级功能
|
||||
|
||||
### 目标
|
||||
|
||||
实现 TCP/UDP Stream 代理、性能优化、优雅升级。
|
||||
|
||||
### 任务列表
|
||||
@ -1019,6 +1013,7 @@ feat(enhance): 实现重写、压缩、缓存和日志功能
|
||||
#### 6.1 TCP/UDP Stream 代理
|
||||
|
||||
**实现**:
|
||||
|
||||
```go
|
||||
// internal/stream/stream.go
|
||||
|
||||
@ -1042,6 +1037,7 @@ type StreamTarget struct {
|
||||
```
|
||||
|
||||
**配置示例**:
|
||||
|
||||
```yaml
|
||||
stream:
|
||||
- listen: 3306
|
||||
@ -1058,6 +1054,7 @@ stream:
|
||||
#### 6.2 优雅升级(热升级)
|
||||
|
||||
**实现**:
|
||||
|
||||
```go
|
||||
// internal/server/upgrade.go
|
||||
|
||||
@ -1071,6 +1068,7 @@ func GracefulUpgrade(newBinary string) error
|
||||
```
|
||||
|
||||
**信号处理**:
|
||||
|
||||
- `SIGUSR2`:触发升级
|
||||
- `SIGWINCH`:优雅关闭 worker
|
||||
|
||||
@ -1079,6 +1077,7 @@ func GracefulUpgrade(newBinary string) error
|
||||
**优化点**:
|
||||
|
||||
##### 6.3.1 连接复用
|
||||
|
||||
```go
|
||||
// http.Transport 连接池配置
|
||||
transport := &http.Transport{
|
||||
@ -1090,6 +1089,7 @@ transport := &http.Transport{
|
||||
```
|
||||
|
||||
##### 6.3.2 缓冲池
|
||||
|
||||
```go
|
||||
// 使用 sync.Pool 实现分级缓冲池
|
||||
var bufferPool = sync.Pool{
|
||||
@ -1100,6 +1100,7 @@ var bufferPool = sync.Pool{
|
||||
```
|
||||
|
||||
##### 6.3.3 零拷贝(sendfile)
|
||||
|
||||
```go
|
||||
// internal/handler/sendfile.go
|
||||
|
||||
@ -1120,6 +1121,7 @@ func SendFile(w http.ResponseWriter, f *os.File, offset, length int64) error {
|
||||
```
|
||||
|
||||
##### 6.3.4 Goroutine 池(可选)
|
||||
|
||||
```go
|
||||
// internal/server/pool.go
|
||||
|
||||
@ -1141,6 +1143,7 @@ performance:
|
||||
```
|
||||
|
||||
##### 6.3.5 对象池
|
||||
|
||||
```go
|
||||
// 使用 sync.Pool 复用对象
|
||||
var requestPool = sync.Pool{
|
||||
@ -1151,6 +1154,7 @@ var requestPool = sync.Pool{
|
||||
```
|
||||
|
||||
##### 6.3.6 代理缓存锁(防击穿)
|
||||
|
||||
```go
|
||||
// internal/cache/proxy_cache.go
|
||||
|
||||
@ -1181,6 +1185,7 @@ type ProxyCache struct {
|
||||
| `SIGUSR2` | 热升级 |
|
||||
|
||||
### 验证方法
|
||||
|
||||
```bash
|
||||
# TCP Stream 测试
|
||||
# 启动 MySQL 后端
|
||||
@ -1195,22 +1200,6 @@ ps aux | grep lolly # 应有两个进程
|
||||
wrk -t4 -c1000 -d30s http://localhost:8080/
|
||||
```
|
||||
|
||||
### 提交信息
|
||||
```
|
||||
feat(advanced): 实现 Stream 代理和高级功能
|
||||
|
||||
- 实现 TCP Stream 代理和负载均衡
|
||||
- 实现 UDP Stream 代理
|
||||
- 实现优雅升级(热升级)
|
||||
- 完善信号处理(SIGHUP、SIGUSR1、SIGUSR2)
|
||||
- 实现性能优化:
|
||||
- 连接池复用(http.Transport 配置)
|
||||
- 分级缓冲池(sync.Pool)
|
||||
- 零拷贝 sendfile(跨平台兼容)
|
||||
- Goroutine 池(可选,高 QPS 场景)
|
||||
- 代理缓存锁(防止缓存击穿)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 文件依赖关系图
|
||||
@ -1255,20 +1244,21 @@ Phase 6:
|
||||
|
||||
## 总体进度追踪
|
||||
|
||||
| 阶段 | 状态 | 主要功能 |
|
||||
|------|------|----------|
|
||||
| Phase 1 | 待开始 | 项目骨架、配置系统 |
|
||||
| 阶段 | 状态 | 主要功能 |
|
||||
| ------- | ------ | ------------------------- |
|
||||
| Phase 1 | 待开始 | 项目骨架、配置系统 |
|
||||
| Phase 2 | 待开始 | HTTP 核心、静态文件、路由 |
|
||||
| Phase 3 | 待开始 | 反向代理、负载均衡 |
|
||||
| Phase 4 | 待开始 | SSL/TLS、安全控制 |
|
||||
| Phase 5 | 待开始 | 重写、压缩、缓存、日志 |
|
||||
| Phase 6 | 待开始 | Stream、性能优化 |
|
||||
| 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`
|
||||
@ -1279,4 +1269,4 @@ Phase 6:
|
||||
- Stream 代理:`docs/10-nginx-stream-tcp-udp.md`
|
||||
- 性能优化:`docs/12-nginx-performance-tuning.md`
|
||||
|
||||
**代码注释规范**:`docs/comments.md`(必须遵循)
|
||||
**代码注释规范**:`docs/comments.md`(必须遵循)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user