diff --git a/docs/README.md b/docs/README.md deleted file mode 100644 index 0d20d85..0000000 --- a/docs/README.md +++ /dev/null @@ -1,194 +0,0 @@ -# NGINX 文档汇总 - -本目录包含 NGINX 官方文档的深度总结,涵盖 NGINX 的所有常用功能。 - -## 文档索引 - -| 序号 | 文档 | 内容概述 | -|------|------|----------| -| 01 | [概述与基础指南](./01-nginx-overview.md) | NGINX 架构、配置结构、启动停止、信号控制、命令行参数 | -| 02 | [安装与构建指南](./02-nginx-installation.md) | Linux 包安装、源码编译、配置参数、依赖库、模块编译 | -| 03 | [HTTP 核心模块](./03-nginx-http-core.md) | server/location 配置、请求路由、文件服务、客户端控制、性能优化 | -| 04 | [反向代理与负载均衡](./04-nginx-proxy-loadbalancing.md) | proxy_pass、upstream、负载均衡算法、健康检查、缓存、WebSocket | -| 05 | [SSL/TLS 与 HTTPS](./05-nginx-ssl-https.md) | HTTPS 配置、SSL 指令、会话缓存、OCSP、SNI、HTTP/2、HTTP/3 | -| 06 | [URL 重写与请求处理](./06-nginx-rewrite.md) | rewrite、return、if、map、常用重写场景、最佳实践 | -| 07 | [压缩与缓存](./07-nginx-compression-caching.md) | Gzip 压缩、代理缓存、FastCGI 缓存、静态文件缓存 | -| 08 | [日志与监控](./08-nginx-logging-monitoring.md) | 访问日志、错误日志、日志格式、条件日志、stub_status、日志分析 | -| 09 | [安全与访问控制](./09-nginx-security.md) | IP 访问控制、基础认证、请求限制、安全头部、防盗链、WAF | -| 10 | [TCP/UDP Stream 模块](./10-nginx-stream-tcp-udp.md) | TCP/UDP 代理、负载均衡、SSL、PROXY 协议、速率限制 | -| 11 | [邮件代理模块](./11-nginx-mail-proxy.md) | IMAP/POP3/SMTP 代理、认证配置、SSL/TLS、认证服务器 | -| 12 | [性能优化](./12-nginx-performance-tuning.md) | Worker 配置、事件优化、连接复用、缓冲配置、内核参数 | -| 13 | [Git Commit 规范](./13-git-commit-guide.md) | Conventional Commits 格式、类型定义、范围划分、示例库 | -| 14 | [gRPC/uWSGI/SCGI 代理](./14-nginx-grpc-uwsgi.md) | gRPC 代理、uWSGI Python 部署、SCGI 通用代理、模块对比 | -| 15 | [高级特性](./15-nginx-advanced-features.md) | 内部重定向、错误处理、请求拦截、高级路由 | -| 16 | [内部重定向](./16-nginx-internal-redirect.md) | internal 指令、X-Accel-Redirect、try_files、命名 location | -| 17 | [镜像与切片](./17-nginx-mirror-slice.md) | mirror 请求镜像、slice 大文件切片、流量复制 | -| 18 | [Memcached 集成](./18-nginx-memcached.md) | memcached_pass、缓存加速、键值设计 | -| 19 | [HTTP 功能模块详解](./19-nginx-http-modules-detail.md) | access/auth/autoindex/geo/map/realip/referer/secure_link/ssi/sub 等 16 个模块 | -| 20 | [限流与连接控制](./20-nginx-rate-limiting.md) | limit_req 请求限流、limit_conn 连接限制、令牌桶算法、DDoS 防护 | -| 21 | [HTTP/2 与 HTTP/3](./21-nginx-http2-http3.md) | HTTP/2 多路复用、HTTP/3 QUIC、配置迁移、性能对比 | -| 22 | [第三方扩展模块](./22-nginx-third-party-modules.md) | NJS/Lua/Brotli/Cache Purge/Headers More/RTMP/Sticky 模块 | -| 23 | [特殊功能模块](./23-nginx-special-modules.md) | WebDAV/图像过滤/FLV/MP4/HLS 流媒体/XSLT 转换 | -| 24 | [核心与事件模块](./24-nginx-core-events.md) | worker_processes/events/epoll/kqueue/连接数计算 | -| 25 | [内置变量速查表](./25-nginx-variables-reference.md) | HTTP/Stream/SSL/Upstream 变量完整列表(150+个) | -| 26 | [Lua 模块深度指南](./26-nginx-lua-guide.md) | OpenResty、ngx_lua 指令、共享字典、cosocket API | -| 27 | [安全深度指南](./27-nginx-security-deep-dive.md) | WAF/ModSecurity、DDoS 防护、OWASP Top 10、安全头部 | -| 28 | [API 网关配置](./28-nginx-api-gateway.md) | API 路由设计、JWT 验证、限流配额、版本控制 | -| 29 | [动态配置与服务发现](./29-nginx-dynamic-config.md) | 动态 upstream、etcd/Consul、dyups、nginx-unit | -| 30 | [njs JavaScript 模块](./30-nginx-njs-guide.md) | njs 引擎、js_import/js_set/js_content、Fetch API、共享字典 | -| 31 | [OpenTelemetry 可观测性](./31-nginx-observability.md) | ngx_otel_module、分布式追踪、Jaeger/Zipkin 集成、采样策略 | -| 32 | [ACME 自动证书管理](./32-nginx-acme-ssl.md) | ngx_http_acme_module、Let's Encrypt、自动续期、HTTP-01/DNS-01 挑战 | - ---- - -## 模块分类索引 - -### 核心模块 -- [核心与事件模块](./24-nginx-core-events.md) - ngx_core_module, ngx_events_module -- [HTTP 核心模块](./03-nginx-http-core.md) - ngx_http_core_module - -### 代理与负载均衡 -- [反向代理与负载均衡](./04-nginx-proxy-loadbalancing.md) - ngx_http_proxy_module, ngx_http_upstream_module -- [gRPC/uWSGI/SCGI 代理](./14-nginx-grpc-uwsgi.md) - gRPC, Python, CGI 代理 -- [TCP/UDP Stream 模块](./10-nginx-stream-tcp-udp.md) - ngx_stream_* 模块 -- [邮件代理模块](./11-nginx-mail-proxy.md) - ngx_mail_* 模块 - -### 安全与访问控制 -- [安全与访问控制](./09-nginx-security.md) - 综合安全配置 -- [HTTP 功能模块详解](./19-nginx-http-modules-detail.md) - access/auth_basic/auth_request/referer/secure_link -- [限流与连接控制](./20-nginx-rate-limiting.md) - limit_req, limit_conn - -### 性能与优化 -- [性能优化](./12-nginx-performance-tuning.md) - Worker/事件/缓冲/内核参数 -- [压缩与缓存](./07-nginx-compression-caching.md) - Gzip, proxy_cache, fastcgi_cache -- [HTTP/2 与 HTTP/3](./21-nginx-http2-http3.md) - HTTP/2, HTTP/3 QUIC - -### 内容处理 -- [URL 重写与请求处理](./06-nginx-rewrite.md) - rewrite, return, map -- [镜像与切片](./17-nginx-mirror-slice.md) - mirror, slice -- [特殊功能模块](./23-nginx-special-modules.md) - WebDAV, 图像过滤, 流媒体 - -### 扩展与第三方 -- [第三方扩展模块](./22-nginx-third-party-modules.md) - NJS, Lua, Brotli, RTMP 等 -- [Lua 模块深度指南](./26-nginx-lua-guide.md) - OpenResty、ngx_lua、cosocket -- [njs JavaScript 模块](./30-nginx-njs-guide.md) - njs 引擎、JavaScript 扩展 - -### 安全深度 -- [安全与访问控制](./09-nginx-security.md) - 综合安全配置 -- [安全深度指南](./27-nginx-security-deep-dive.md) - WAF、DDoS、OWASP -- [ACME 自动证书管理](./32-nginx-acme-ssl.md) - Let's Encrypt、自动 SSL 证书 - -### 可观测性 -- [日志与监控](./08-nginx-logging-monitoring.md) - 访问日志、错误日志、stub_status -- [OpenTelemetry 可观测性](./31-nginx-observability.md) - 分布式追踪、Jaeger/Zipkin - -### API 与动态配置 -- [API 网关配置](./28-nginx-api-gateway.md) - API 路由、JWT、限流配额 -- [动态配置与服务发现](./29-nginx-dynamic-config.md) - 动态 upstream、etcd/Consul - -### 参考手册 -- [内置变量速查表](./25-nginx-variables-reference.md) - 150+ 个变量完整列表 - -## 快速参考 - -### 核心配置结构 - -```nginx -# 全局配置 -worker_processes auto; -error_log /var/log/nginx/error.log; - -events { - worker_connections 10240; -} - -http { - # HTTP 全局配置 - include mime.types; - default_type application/octet-stream; - - # 上游服务器 - upstream backend { - server 192.168.1.1:8080; - server 192.168.1.2:8080; - } - - server { - listen 80; - server_name example.com; - - location / { - proxy_pass http://backend; - } - } -} - -stream { - # TCP/UDP 代理 - server { - listen 3306; - proxy_pass mysql:3306; - } -} - -mail { - # 邮件代理 - server { - listen 25; - protocol smtp; - } -} -``` - -### 常用命令 - -```bash -# 测试配置 -nginx -t - -# 重载配置 -nginx -s reload - -# 优雅停止 -nginx -s quit - -# 查看版本和编译参数 -nginx -V -``` - -### 性能优化要点 - -1. **Worker 进程**:`worker_processes auto` -2. **连接数**:`worker_connections 10240` -3. **文件传输**:`sendfile on` -4. **长连接**:`keepalive_timeout 65` -5. **压缩**:`gzip on; gzip_comp_level 6` -6. **缓存**:`open_file_cache` + `proxy_cache` -7. **SSL 优化**:`ssl_session_cache shared:SSL:10m` - -### 安全配置要点 - -1. **隐藏版本**:`server_tokens off` -2. **安全协议**:`ssl_protocols TLSv1.2 TLSv1.3` -3. **安全头部**:HSTS、X-Frame-Options、CSP -4. **请求限制**:`limit_req` + `limit_conn` -5. **访问控制**:IP 白名单 + 基础认证 - ---- - -## 官方资源 - -- **官方网站**:https://nginx.org/ -- **官方文档**:https://nginx.org/en/docs/ -- **模块参考**:https://nginx.org/en/docs/ngx_core_module.html -- **FAQ**:https://nginx.org/en/docs/faq.html -- **Wiki**:https://wiki.nginx.org/ - ---- - -## 版本说明 - -- 文档基于 NGINX 官方文档整理 -- 涵盖 NGINX 开源版主要功能 -- 部分高级功能需要 NGINX Plus 商业版 -- 建议使用 NGINX 1.24+ 版本以获得最新特性 \ No newline at end of file diff --git a/docs/config-reference.md b/docs/config-reference.md deleted file mode 100644 index b59733c..0000000 --- a/docs/config-reference.md +++ /dev/null @@ -1,511 +0,0 @@ -# Lolly 配置文件完整字段清单 - -> 本文档列出所有支持的配置字段及其枚举值,与代码定义完全同步。 - -## 顶层配置 - -| 字段 | 类型 | 说明 | -|------|------|------| -| `server` | ServerConfig | 单服务器模式配置 | -| `servers` | []ServerConfig | 多虚拟主机模式配置 | -| `stream` | []StreamConfig | TCP/UDP Stream 代理配置 | -| `http3` | HTTP3Config | HTTP/3 (QUIC) 配置 | -| `logging` | LoggingConfig | 日志配置 | -| `performance` | PerformanceConfig | 性能配置 | -| `monitoring` | MonitoringConfig | 监控配置 | - ---- - -## ServerConfig 服务器配置 - -| 字段 | 类型 | 默认值 | 说明 | -|------|------|--------|------| -| `listen` | string | `:8080` | 监听地址,格式 `host:port` 或 `:port` | -| `name` | string | `localhost` | 服务器名称,虚拟主机匹配 | -| `static` | []StaticConfig | - | 静态文件服务配置 | -| `proxy` | []ProxyConfig | - | 反向代理规则列表 | -| `ssl` | SSLConfig | - | SSL/TLS 配置 | -| `security` | SecurityConfig | - | 安全配置 | -| `rewrite` | []RewriteRule | - | URL 重写规则 | -| `compression` | CompressionConfig | - | 响应压缩配置 | -| `read_timeout` | duration | `30s` | 读取超时 | -| `write_timeout` | duration | `30s` | 写入超时 | -| `idle_timeout` | duration | `120s` | 空闲超时 | -| `max_conns_per_ip` | int | `1000` | 每 IP 最大连接数 | -| `max_requests_per_conn` | int | `10000` | 每连接最大请求数 | -| `client_max_body_size` | string | `1MB` | **请求体大小限制** | - -### client_max_body_size 格式 - -支持以下格式: -- 纯数字:表示字节数,如 `1048576` -- 带单位:`1b`, `10kb`, `5mb`, `1gb` -- 默认值:`1MB` - ---- - -## StaticConfig 静态文件配置 - -| 字段 | 类型 | 默认值 | 说明 | -|------|------|--------|------| -| `path` | string | `/` | 匹配路径前缀 | -| `root` | string | - | 静态文件根目录 | -| `index` | []string | `["index.html", "index.htm"]` | 索引文件列表 | -| `try_files` | []string | - | **按顺序尝试查找的文件,支持 SPA** | -| `try_files_pass` | bool | `false` | **内部重定向是否触发中间件** | - -### try_files 示例 - -```yaml -static: - - path: "/" - root: "/var/www/html" - index: ["index.html"] - try_files: ["$uri", "$uri/", "/index.html"] # SPA 部署 - try_files_pass: false # 内部重定向不触发中间件 -``` - -**占位符支持:** -- `$uri` - 原始请求 URI -- `$uri/` - URI 作为目录 - ---- - -## ProxyConfig 反向代理配置 - -| 字段 | 类型 | 默认值 | 说明 | -|------|------|--------|------| -| `path` | string | **必填** | 匹配路径前缀 | -| `targets` | []ProxyTarget | **必填** | 后端目标列表 | -| `load_balance` | string | `round_robin` | 负载均衡算法 | -| `hash_key` | string | - | 一致性哈希键 | -| `virtual_nodes` | int | `150` | 一致性哈希虚拟节点数 | -| `health_check` | HealthCheckConfig | - | 健康检查配置 | -| `timeout` | ProxyTimeout | - | 超时配置 | -| `headers` | ProxyHeaders | - | 请求/响应头修改 | -| `cache` | ProxyCacheConfig | - | 代理缓存配置 | -| `client_max_body_size` | string | - | **请求体大小限制(覆盖全局)** | -| `next_upstream` | NextUpstreamConfig | - | 故障转移配置 | - -### load_balance 枚举值 - -| 值 | 说明 | -|-----|------| -| `round_robin` | 轮询(默认) | -| `weighted_round_robin` | 加权轮询 | -| `least_conn` | 最少连接 | -| `ip_hash` | IP 哈希 | -| `consistent_hash` | 一致性哈希 | - -### hash_key 枚举值 - -| 值 | 说明 | -|-----|------| -| `ip` | 客户端 IP | -| `uri` | 请求 URI | -| `header:X-Name` | 指定请求头的值 | - ---- - -## SSLConfig SSL/TLS 配置 - -| 字段 | 类型 | 默认值 | 说明 | -|------|------|--------|------| -| `cert` | string | - | 证书文件路径(PEM 格式) | -| `key` | string | - | 私钥文件路径(PEM 格式) | -| `cert_chain` | string | - | 证书链文件路径 | -| `protocols` | []string | `["TLSv1.2", "TLSv1.3"]` | TLS 版本 | -| `ciphers` | []string | - | 加密套件(仅 TLS 1.2 有效) | -| `ocsp_stapling` | bool | `false` | OCSP Stapling | -| `hsts` | HSTSConfig | - | HSTS 配置 | - -### protocols 枚举值 - -| 值 | 说明 | -|-----|------| -| `TLSv1.2` | TLS 1.2 | -| `TLSv1.3` | TLS 1.3(推荐) | - -**注意**:不支持 `TLSv1.0` 和 `TLSv1.1`(已废弃) - -### ciphers 安全要求 - -拒绝包含以下关键字的不安全套件: -- `RC4` -- `DES` -- `3DES` -- `CBC` - -推荐套件: -``` -ECDHE-ECDSA-AES256-GCM-SHA384 -ECDHE-RSA-AES256-GCM-SHA384 -ECDHE-ECDSA-CHACHA20-POLY1305 -ECDHE-RSA-CHACHA20-POLY1305 -``` - ---- - -## HSTSConfig HSTS 配置 - -| 字段 | 类型 | 默认值 | 说明 | -|------|------|--------|------| -| `max_age` | int | `31536000` | 过期时间(秒),1年 | -| `include_sub_domains` | bool | `true` | 包含子域名 | -| `preload` | bool | `false` | 加入 HSTS 预加载列表 | - ---- - -## SecurityConfig 安全配置 - -| 字段 | 类型 | 默认值 | 说明 | -|------|------|--------|------| -| `access` | AccessConfig | - | IP 访问控制 | -| `rate_limit` | RateLimitConfig | - | 速率限制 | -| `auth` | AuthConfig | - | 认证配置 | -| `headers` | SecurityHeaders | - | 安全头部 | -| `error_page` | ErrorPageConfig | - | **自定义错误页面** | - ---- - -## ErrorPageConfig 错误页面配置 - -| 字段 | 类型 | 默认值 | 说明 | -|------|------|--------|------| -| `pages` | map[int]string | - | 状态码到错误页面映射 | -| `default` | string | - | 默认错误页面 | -| `response_code` | int | `0` | 响应状态码覆盖 | - -### 示例 - -```yaml -security: - error_page: - pages: - 404: "/var/www/errors/404.html" - 500: "/var/www/errors/500.html" - 502: "/var/www/errors/502.html" - 503: "/var/www/errors/503.html" - default: "/var/www/errors/error.html" - response_code: 200 # 可选:所有错误返回 200 -``` - ---- - -## AccessConfig 访问控制配置 - -| 字段 | 类型 | 默认值 | 说明 | -|------|------|--------|------| -| `allow` | []string | `[]` | 允许的 IP/CIDR 列表 | -| `deny` | []string | `[]` | 拒绝的 IP/CIDR 列表 | -| `default` | string | `allow` | 默认动作 | -| `trusted_proxies` | []string | `[]` | 可信代理 CIDR | - -### default 枚举值 - -| 值 | 说明 | -|-----|------| -| `allow` | 默认允许 | -| `deny` | 默认拒绝 | - ---- - -## RateLimitConfig 速率限制配置 - -| 字段 | 类型 | 默认值 | 说明 | -|------|------|--------|------| -| `request_rate` | int | `0` | 每秒请求数限制(0=不限制) | -| `burst` | int | `0` | 突发上限 | -| `conn_limit` | int | `0` | 连接数限制 | -| `key` | string | `ip` | 限流 key 来源 | -| `algorithm` | string | `token_bucket` | 限流算法 | -| `sliding_window_mode` | string | `approximate` | 滑动窗口模式 | -| `sliding_window` | int | `60` | 滑动窗口大小(秒) | - -### key 枚举值 - -| 值 | 说明 | -|-----|------| -| `ip` | 客户端 IP | -| `header` | 请求头值 | - -### algorithm 枚举值 - -| 值 | 说明 | -|-----|------| -| `token_bucket` | 令牌桶(默认) | -| `sliding_window` | 滑动窗口 | - -### sliding_window_mode 枚举值 - -| 值 | 说明 | -|-----|------| -| `approximate` | 近似模式(高性能) | -| `precise` | 精确模式(高精度) | - ---- - -## AuthConfig 认证配置 - -| 字段 | 类型 | 默认值 | 说明 | -|------|------|--------|------| -| `type` | string | - | 认证类型(空=禁用) | -| `require_tls` | bool | `true` | 强制 HTTPS | -| `algorithm` | string | `bcrypt` | 密码哈希算法 | -| `users` | []User | - | 用户列表 | -| `realm` | string | `Restricted Area` | 认证域 | -| `min_password_length` | int | `8` | 密码最小长度 | - -### type 枚举值 - -| 值 | 说明 | -|-----|------| -| ` ` (空) | 禁用认证 | -| `basic` | HTTP Basic 认证 | - -### algorithm 枚举值 - -| 值 | 说明 | -|-----|------| -| `bcrypt` | bcrypt 算法(默认) | -| `argon2id` | Argon2id 算法 | - ---- - -## SecurityHeaders 安全头部配置 - -| 字段 | 类型 | 默认值 | 说明 | -|------|------|--------|------| -| `x_frame_options` | string | `DENY` | 防止点击劫持 | -| `x_content_type_options` | string | `nosniff` | 防止 MIME 嗅探 | -| `content_security_policy` | string | - | CSP 策略 | -| `referrer_policy` | string | `strict-origin-when-cross-origin` | 引用策略 | -| `permissions_policy` | string | - | 权限策略 | - -### x_frame_options 枚举值 - -| 值 | 说明 | -|-----|------| -| ` ` (空) | 禁用 | -| `DENY` | 完全禁止嵌入 | -| `SAMEORIGIN` | 仅允许同源嵌入 | - -### referrer_policy 枚举值 - -| 值 | 说明 | -|-----|------| -| `no-referrer` | 不发送 Referer | -| `no-referrer-when-downgrade` | 降级时不发送 | -| `origin` | 仅发送源 | -| `origin-when-cross-origin` | 跨域时仅发送源 | -| `same-origin` | 同源时发送完整 | -| `strict-origin` | 严格模式仅发送源 | -| `strict-origin-when-cross-origin` | 默认值 | -| `unsafe-url` | 始终发送完整 URL | - ---- - -## RewriteRule URL 重写规则 - -| 字段 | 类型 | 默认值 | 说明 | -|------|------|--------|------| -| `pattern` | string | **必填** | 正则匹配模式 | -| `replacement` | string | **必填** | 替换目标 | -| `flag` | string | - | 标志 | - -### flag 枚举值 - -| 值 | 说明 | -|-----|------| -| ` ` (空) | 继续匹配后续规则 | -| `last` | 停止匹配后续规则 | -| `break` | 停止匹配但继续处理 | -| `redirect` | 302 临时重定向 | -| `permanent` | 301 永久重定向 | - ---- - -## CompressionConfig 压缩配置 - -| 字段 | 类型 | 默认值 | 说明 | -|------|------|--------|------| -| `type` | string | `gzip` | 压缩类型 | -| `level` | int | `6` | 压缩级别(0-9) | -| `min_size` | int | `1024` | 最小压缩大小(字节) | -| `types` | []string | 见下方 | 可压缩的 MIME 类型 | -| `gzip_static` | bool | `false` | 启用预压缩文件支持 | -| `gzip_static_extensions` | []string | `[".br", ".gz"]` | 预压缩文件扩展名 | - -### type 枚举值 - -| 值 | 说明 | -|-----|------| -| ` ` (空) | 禁用压缩 | -| `gzip` | 仅 gzip | -| `brotli` | 仅 brotli | -| `both` | gzip + brotli | - -### 默认可压缩 MIME 类型 - -```yaml -types: - - "text/html" - - "text/css" - - "text/javascript" - - "application/json" - - "application/javascript" -``` - ---- - -## NextUpstreamConfig 故障转移配置 - -| 字段 | 类型 | 默认值 | 说明 | -|------|------|--------|------| -| `tries` | int | `1` | 最大尝试次数 | -| `http_codes` | []int | - | 触发重试的 HTTP 状态码 | - -**注意**:`tries=1` 表示禁用故障转移 - -### 示例 - -```yaml -next_upstream: - tries: 3 - http_codes: [502, 503, 504] -``` - ---- - -## StreamConfig TCP/UDP Stream 代理 - -| 字段 | 类型 | 默认值 | 说明 | -|------|------|--------|------| -| `listen` | string | **必填** | 监听地址 | -| `protocol` | string | **必填** | 协议类型 | -| `upstream` | StreamUpstream | - | 上游配置 | - -### protocol 枚举值 - -| 值 | 说明 | -|-----|------| -| `tcp` | TCP 协议 | -| `udp` | UDP 协议 | - ---- - -## HTTP3Config HTTP/3 配置 - -| 字段 | 类型 | 默认值 | 说明 | -|------|------|--------|------| -| `enabled` | bool | `false` | 是否启用 | -| `listen` | string | `:443` | UDP 监听地址 | -| `max_streams` | int | `100` | 最大并发流 | -| `idle_timeout` | duration | `60s` | 空闲超时 | -| `enable_0rtt` | bool | `false` | 启用 0-RTT | - ---- - -## LoggingConfig 日志配置 - -| 字段 | 类型 | 默认值 | 说明 | -|------|------|--------|------| -| `format` | string | `text` | 全局日志格式 | -| `access` | AccessLogConfig | - | 访问日志配置 | -| `error` | ErrorLogConfig | - | 错误日志配置 | - -### format 枚举值 - -| 值 | 说明 | -|-----|------| -| `text` | 文本格式(默认) | -| `json` | JSON 格式 | - -### access.format 支持变量 - -| 变量 | 说明 | -|------|------| -| `$remote_addr` | 客户端 IP | -| `$remote_user` | 认证用户名 | -| `$request` | 请求行 | -| `$status` | 响应状态码 | -| `$body_bytes_sent` | 响应体大小 | -| `$request_time` | 请求处理时间 | -| `$http_referer` | Referer 头 | -| `$http_user_agent` | User-Agent 头 | -| `$time` | 时间戳(RFC3339) | - -### error.level 枚举值 - -| 值 | 说明 | -|-----|------| -| `debug` | 调试级别 | -| `info` | 信息级别(默认) | -| `warn` | 警告级别 | -| `error` | 错误级别 | - ---- - -## PerformanceConfig 性能配置 - -| 字段 | 类型 | 默认值 | 说明 | -|------|------|--------|------| -| `goroutine_pool` | GoroutinePoolConfig | - | Goroutine 池配置 | -| `file_cache` | FileCacheConfig | - | 文件缓存配置 | -| `transport` | TransportConfig | - | HTTP Transport 配置 | - -### GoroutinePoolConfig - -| 字段 | 类型 | 默认值 | 说明 | -|------|------|--------|------| -| `enabled` | bool | `false` | 是否启用 | -| `max_workers` | int | `1000` | 最大 worker 数 | -| `min_workers` | int | `10` | 最小 worker 数(预热) | -| `idle_timeout` | duration | `60s` | 空闲超时 | - -### FileCacheConfig - -| 字段 | 类型 | 默认值 | 说明 | -|------|------|--------|------| -| `max_entries` | int64 | `10000` | 最大缓存条目数 | -| `max_size` | int64 | `268435456` (256MB) | 内存上限 | -| `inactive` | duration | `20s` | 未访问淘汰时间 | - -### TransportConfig - -| 字段 | 类型 | 默认值 | 说明 | -|------|------|--------|------| -| `max_idle_conns` | int | `100` | 最大空闲连接数 | -| `max_idle_conns_per_host` | int | `32` | 每主机空闲连接 | -| `idle_conn_timeout` | duration | `90s` | 空闲超时 | -| `max_conns_per_host` | int | `0` | 每主机最大连接(0=不限制) | - ---- - -## MonitoringConfig 监控配置 - -| 字段 | 类型 | 默认值 | 说明 | -|------|------|--------|------| -| `status` | StatusConfig | - | 状态端点配置 | -| `pprof` | PprofConfig | - | pprof 配置 | - -### StatusConfig - -| 字段 | 类型 | 默认值 | 说明 | -|------|------|--------|------| -| `path` | string | `/_status` | 端点路径 | -| `allow` | []string | `["127.0.0.1"]` | 允许访问的 IP | - -### PprofConfig - -| 字段 | 类型 | 默认值 | 说明 | -|------|------|--------|------| -| `enabled` | bool | `false` | 是否启用 | -| `path` | string | `/debug/pprof` | 端点路径前缀 | -| `allow` | []string | `["127.0.0.1"]` | 允许访问的 IP | - ---- - -## 变更记录 - -- 2026-04-07: 首次创建,发现 `--generate-config` 缺少 `client_max_body_size`、`try_files`、`try_files_pass`、`error_page` 字段 \ No newline at end of file diff --git a/docs/nginx-docs-analysis.md b/docs/nginx-docs-analysis.md deleted file mode 100644 index beddf21..0000000 --- a/docs/nginx-docs-analysis.md +++ /dev/null @@ -1,288 +0,0 @@ -# NGINX 文档完善建议 - -基于对 nginx.org 官方文档的深度分析,对比 docs/ 目录下现有的 25 个文档,识别出以下可完善的部分。 - ---- - -## 一、缺失或需要新增的文档 - -### 1. NGINX Lua 模块深度指南 -**优先级:高** - -现有 `22-nginx-third-party-modules.md` 对 NJS/Lua 有简要介绍,但 Lua 模块功能强大,值得独立文档。 - -**建议内容:** -- OpenResty 环境搭建 -- ngx_lua 核心指令(content_by_lua、access_by_lua、rewrite_by_lua) -- Lua 共享字典(ngx.shared.DICT) -- cosocket API(非阻塞网络 I/O) -- 与 Redis/MySQL 集成 -- 性能优化技巧 - -### 2. NGINX 作为 API 网关 -**优先级:中** - -现代架构中 nginx 常作为 API 网关使用。 - -**建议内容:** -- API 路由设计模式 -- 请求/响应转换 -- JWT 验证(通过 Lua 或 NJS) -- 限流与配额管理 -- API 版本控制策略 -- OpenAPI/Swagger 集成 - -### 3. NGINX 动态配置 -**优先级:中** - -现代部署需要动态配置能力。 - -**建议内容:** -- 动态 upstream(nginx-plus 或开源方案) -- 使用 etcd/Consul 进行服务发现 -- dyups 模块使用 -- nginx-unit 简介 -- 动态 SSL 证书加载 - -### 4. NGINX 安全最佳实践(增强版) -**优先级:高** - -现有 `09-nginx-security.md` 内容良好,可扩展: - -**建议补充:** -- Bot 检测与防护 -- WAF 配置深度指南(ModSecurity) -- DDoS 防护策略 -- OWASP Top 10 防护 -- 安全响应头完整配置 -- CVE 历史漏洞与修复版本 - ---- - -## 二、现有文档可扩展的内容 - -### 15-nginx-advanced-features.md -**当前:** 仅 94 行,内容相对简略 -**建议扩展:** - -1. **调试与诊断** - - debug 日志级别 - - debug_points 指令 - - worker_debug_connection - -2. **错误处理** - - error_page 高级用法 - - 自定义错误页面 - - try_files 与 error_page 配合 - -3. **请求拦截** - - post_action 指令 - - 日志记录后操作 - -### 16-nginx-internal-redirect.md -**当前:** 119 行,内容较好 -**建议扩展:** - -1. **SSI(服务端包含)详解** - - SSI 指令列表 - - 虚拟包含 vs 文件包含 - - 条件执行 - -2. **命名 location 深度解析** - - 命名 location 语法 - - 与 error_page 配合 - - 重定向链追踪 - -### 17-nginx-mirror-slice.md -**当前:** 143 行,内容较好 -**建议扩展:** - -1. **高级镜像场景** - - 条件镜像(基于请求头、路径) - - 镜像流量采样 - - 镜像目标选择策略 - -2. **slice 与缓存高级配置** - - 多级缓存配置 - - 缓存预热策略 - - 缓存失效策略 - -### 19-nginx-http-modules-detail.md -**当前:** 约 1200 行,内容丰富 -**建议补充:** - -1. **ngx_http_addition_module** - - before/after 内容追加 - - 与 SSI 配合使用 - -2. **ngx_http_sub_module 高级用法** - - 多规则替换 - - 正则替换 - - 变量替换 - ---- - -## 三、新增文档建议清单 - -| 序号 | 文档名称 | 优先级 | 预计行数 | -|------|----------|--------|----------| -| 26 | nginx-lua-guide.md | 高 | 800+ | -| 27 | nginx-api-gateway.md | 中 | 600+ | -| 28 | nginx-dynamic-config.md | 中 | 500+ | -| 29 | nginx-security-deep-dive.md | 高 | 700+ | -| 30 | nginx-troubleshooting.md | 中 | 400+ | -| 31 | nginx-observability.md | 中 | 500+ | - ---- - -## 四、文档质量建议 - -### 统一格式 -- 所有文档使用统一的标题层级 -- 配置示例添加语法高亮标记 -- 表格格式统一 - -### 交叉引用 -- 添加相关文档链接 -- 引用官方文档链接 - -### 版本标注 -- 功能版本要求标注 -- 已废弃功能标注 - ---- - -## 五、NGINX HTTP 模块深度分析(Agent 分析结果) - -### 5.1 HTTP 模块完整列表(按类别) - -#### 核心模块 -| 模块名称 | 功能描述 | 依赖关系 | -|----------|----------|----------| -| `ngx_http_core_module` | HTTP 核心功能 | 无(必需) | -| `ngx_http_log_module` | 访问日志记录 | core | -| `ngx_http_upstream_module` | 上游服务器负载均衡 | core | - -#### 请求处理与路由模块 -| 模块名称 | 功能描述 | 依赖关系 | -|----------|----------|----------| -| `ngx_http_rewrite_module` | URI 重写(支持正则) | core | -| `ngx_http_proxy_module` | 反向代理 | upstream | -| `ngx_http_fastcgi_module` | FastCGI 协议代理 | upstream | -| `ngx_http_uwsgi_module` | uWSGI 协议代理 | upstream | -| `ngx_http_scgi_module` | SCGI 协议代理 | upstream | - -#### 安全与访问控制模块 -| 模块名称 | 功能描述 | 依赖关系 | -|----------|----------|----------| -| `ngx_http_access_module` | IP 访问控制 | core | -| `ngx_http_auth_basic_module` | HTTP 基本认证 | core | -| `ngx_http_auth_request_module` | 子请求认证 | proxy | -| `ngx_http_ssl_module` | SSL/TLS 支持 | core | -| `ngx_http_limit_req_module` | 请求速率限制 | core | -| `ngx_http_limit_conn_module` | 连接数限制 | core | -| `ngx_http_realip_module` | 真实 IP 替换 | core | - -#### 压缩与优化模块 -| 模块名称 | 功能描述 | 依赖关系 | -|----------|----------|----------| -| `ngx_http_gzip_module` | GZIP 压缩 | core | -| `ngx_http_gunzip_module` | GZIP 解压 | gzip | -| `ngx_http_headers_module` | 响应头处理 | core | - -#### 上游负载均衡算法模块 -| 模块名称 | 功能描述 | 依赖关系 | -|----------|----------|----------| -| `ngx_http_upstream_hash_module` | 一致性哈希负载均衡 | upstream | -| `ngx_http_upstream_ip_hash_module` | IP 哈希负载均衡 | upstream | -| `ngx_http_upstream_least_conn_module` | 最少连接负载均衡 | upstream | -| `ngx_http_upstream_keepalive_module` | 上游 keepalive 连接 | upstream | - -### 5.2 最常用的 15 个指令 - -| 排名 | 指令 | 用途 | -|------|------|------| -| 1 | `listen` | 端口监听 | -| 2 | `server_name` | 虚拟主机 | -| 3 | `location` | 路由匹配 | -| 4 | `root` | 根目录 | -| 5 | `proxy_pass` | 代理目标 | -| 6 | `try_files` | 文件尝试 | -| 7 | `rewrite` | URL 重写 | -| 8 | `return` | 返回响应 | -| 9 | `index` | 索引文件 | -| 10 | `error_page` | 错误页面 | -| 11 | `client_max_body_size` | 上传限制 | -| 12 | `keepalive_timeout` | 连接保持 | -| 13 | `gzip` | 压缩开关 | -| 14 | `ssl_certificate` | SSL 证书 | -| 15 | `access_log` | 访问日志 | - ---- - -## 六、NGINX Stream 模块深度分析(Agent 分析结果) - -### 6.1 Stream 核心模块指令 - -| 指令 | 语法 | 上下文 | 说明 | -|------|------|--------|------| -| `stream` | `stream { ... }` | main | 定义 stream 配置块 | -| `server` | `server { ... }` | stream | 定义虚拟服务器 | -| `listen` | `listen address:port [options]` | server | 监听端口配置 | -| `preread_buffer_size` | `preread_buffer_size size` | stream, server | 预读取缓冲区大小 | -| `preread_timeout` | `preread_timeout timeout` | stream, server | 预读取超时时间 | - -### 6.2 Stream 子模块完整列表 - -| 模块名称 | 功能描述 | -|----------|----------| -| **核心模块** | | -| ngx_stream_core_module | Stream 核心功能 | -| **代理模块** | | -| ngx_stream_proxy_module | TCP/UDP 代理转发 | -| ngx_stream_ssl_module | SSL/TLS 支持 | -| ngx_stream_ssl_preread_module | SSL 预读取(SNI 路由) | -| **上游模块** | | -| ngx_stream_upstream_module | 上游服务器管理 | -| ngx_stream_hash_module | 一致性哈希负载均衡 | -| ngx_stream_least_conn_module | 最少连接负载均衡 | -| ngx_stream_random_module | 随机负载均衡 | -| **访问控制** | | -| ngx_stream_access_module | 允许/拒绝访问控制 | -| ngx_stream_limit_conn_module | 连接数限制 | -| ngx_stream_geo_module | 基于 IP 的地理位置变量 | -| ngx_stream_geoip_module | GeoIP 数据库支持 | -| **日志与监控** | | -| ngx_stream_log_module | 日志记录 | -| ngx_stream_return_module | 返回指定值并关闭连接 | - -### 6.3 现有文档 10-nginx-stream-tcp-udp.md 对比 - -现有文档已覆盖: -- ✅ TCP/UDP 代理基础配置 -- ✅ 负载均衡算法 -- ✅ SSL 终止 -- ✅ PROXY 协议 -- ✅ 速率限制 - -建议补充: -- 🔧 健康检查详细配置(active health check) -- 🔧 stream 日志格式自定义 -- 🔧 UDP 响应数配置(proxy_responses) -- 🔧 SSL preread 模块(SNI 路由) - ---- - -## 七、与 Lolly 项目的关系 - -基于 docs/plan.md,Lolly 是一个类似 nginx 的 Go 实现。文档完善有助于: - -1. **功能对齐**:识别 nginx 功能,作为 Lolly 开发参考 -2. **配置翻译**:nginx 配置 → YAML 配置设计参考 -3. **测试用例**:文档中的配置示例可作为测试用例 - -建议在 Lolly 开发过程中,同步更新 nginx 文档作为功能对照。 - ---- - -*生成时间:2026-04-03* \ No newline at end of file diff --git a/docs/nginx-modules-outline.md b/docs/nginx-modules-outline.md deleted file mode 100644 index 8dd16df..0000000 --- a/docs/nginx-modules-outline.md +++ /dev/null @@ -1,389 +0,0 @@ -# nginx 模块文档大纲 - -## 1. ngx_http_grpc_module (gRPC 代理) - -### 1.1 模块概述 - -ngx_http_grpc_module 模块用于将请求代理到 gRPC 服务器。该模块自 nginx 1.13.10 版本开始提供,支持 HTTP/2 协议上的 gRPC 通信。 - -**主要特性:** -- 支持 gRPC-over-HTTP/2 协议 -- 支持 gRPC 服务端流、客户端流和双向流 -- 支持 SSL/TLS 加密连接 -- 支持负载均衡和健康检查 -- 支持请求头自定义和超时配置 - -### 1.2 核心指令表格 - -| 指令 | 语法 | 说明 | 默认值 | 上下文 | -|------|------|------|--------|--------| -| grpc_pass | `grpc_pass address;` | 设置 gRPC 服务器地址 | - | location, if in location | -| grpc_set_header | `grpc_set_header field value;` | 设置传递给 gRPC 服务器的请求头 | - | http, server, location | -| grpc_hide_header | `grpc_hide_header field;` | 隐藏 gRPC 响应中的指定头字段 | - | http, server, location | -| grpc_pass_header | `grpc_pass_header field;` | 允许传递隐藏的头字段 | - | http, server, location | -| grpc_buffer_size | `grpc_buffer_size size;` | 设置读取响应的缓冲区大小 | 4k/8k | http, server, location | -| grpc_buffering | `grpc_buffering on/off;` | 启用/禁用响应缓冲 | on | http, server, location | -| grpc_connect_timeout | `grpc_connect_timeout time;` | 设置与服务器建立连接的超时 | 60s | http, server, location | -| grpc_send_timeout | `grpc_send_timeout time;` | 设置向服务器发送请求的超时 | 60s | http, server, location | -| grpc_read_timeout | `grpc_read_timeout time;` | 设置读取服务器响应的超时 | 60s | http, server, location | -| grpc_socket_keepalive | `grpc_socket_keepalive on/off;` | 启用 TCP keepalive | off | http, server, location | -| grpc_ssl_certificate | `grpc_ssl_certificate file;` | 指定客户端 SSL 证书 | - | http, server | -| grpc_ssl_certificate_key | `grpc_ssl_certificate_key file;` | 指定客户端 SSL 证书密钥 | - | http, server | -| grpc_ssl_ciphers | `grpc_ssl_ciphers ciphers;` | 指定 SSL 加密算法 | DEFAULT | http, server | -| grpc_ssl_protocols | `grpc_ssl_protocols protocols;` | 指定 SSL 协议版本 | TLSv1 TLSv1.1 TLSv1.2 | http, server | -| grpc_ssl_verify | `grpc_ssl_verify on/off;` | 启用服务器证书验证 | off | http, server | - -### 1.3 配置示例 - -**基本配置:** -```nginx -location / { - grpc_pass grpc://localhost:50051; -} -``` - -**带 SSL 的配置:** -```nginx -location / { - grpc_pass grpcs://grpc.example.com:443; - grpc_ssl_certificate /etc/nginx/client.crt; - grpc_ssl_certificate_key /etc/nginx/client.key; - grpc_ssl_verify on; - grpc_ssl_trusted_certificate /etc/nginx/ca.crt; -} -``` - -**自定义请求头:** -```nginx -location / { - grpc_set_header Host $host; - grpc_set_header X-Real-IP $remote_addr; - grpc_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - grpc_set_header X-Forwarded-Proto $scheme; - grpc_pass grpc://localhost:50051; -} -``` - -**超时和缓冲配置:** -```nginx -location / { - grpc_pass grpc://localhost:50051; - grpc_connect_timeout 5s; - grpc_send_timeout 10s; - grpc_read_timeout 30s; - grpc_buffering off; - grpc_buffer_size 16k; -} -``` - -**负载均衡配置:** -```nginx -upstream grpc_backend { - server 127.0.0.1:50051 weight=5; - server 127.0.0.1:50052; - server 127.0.0.1:50053 backup; - keepalive 32; -} - -location / { - grpc_pass grpc://grpc_backend; - grpc_socket_keepalive on; -} -``` - -### 1.4 与普通 HTTP 代理的区别 - -| 特性 | gRPC 代理 | 普通 HTTP 代理 (proxy_pass) | -|------|-----------|------------------------------| -| 协议 | HTTP/2 必须 | HTTP/1.0, HTTP/1.1, HTTP/2 | -| 传输 | 二进制协议 (Protocol Buffers) | 文本协议 | -| 流支持 | 原生支持双向流 | 需要特殊配置 (chunked) | -| 连接复用 | 多路复用 (Multiplexing) | 连接池 | -| 头部传递 | 使用 grpc_set_header | 使用 proxy_set_header | -| 错误处理 | gRPC 状态码 | HTTP 状态码 | - -### 1.5 应用场景 - -1. **微服务架构网关**:作为 gRPC 服务的统一入口 -2. **SSL/TLS 终止**:对外提供 HTTPS,内部使用明文 gRPC -3. **负载均衡**:在多个 gRPC 服务实例间分发请求 -4. **A/B 测试**:基于路由规则将流量导向不同版本的服务 -5. **流量监控**:收集 gRPC 调用指标和日志 - ---- - -## 2. ngx_http_uwsgi_module (uWSGI 代理) - -### 2.1 模块概述 - -ngx_http_uwsgi_module 模块用于将请求代理到 uwsgi 协议服务器,主要用于 Python WSGI 应用程序(如 Django、Flask)的部署。 - -**主要特性:** -- 专为 Python WSGI 应用设计 -- 使用 uwsgi 协议(比 HTTP/FastCGI 更高效) -- 支持 Unix 域套接字和 TCP 套接字 -- 支持参数传递和环境变量设置 -- 支持缓冲、缓存和超时配置 - -### 2.2 核心指令表格 - -| 指令 | 语法 | 说明 | 默认值 | 上下文 | -|------|------|------|--------|--------| -| uwsgi_pass | `uwsgi_pass address;` | 设置 uwsgi 服务器地址 | - | location, if in location | -| uwsgi_param | `uwsgi_param parameter value [if_not_empty];` | 设置传递给 uWSGI 的参数 | - | http, server, location | -| uwsgi_modifier1 | `uwsgi_modifier1 number;` | 设置 uWSGI 数据包修饰符1 | 0 | http, server, location | -| uwsgi_modifier2 | `uwsgi_modifier2 number;` | 设置 uWSGI 数据包修饰符2 | 0 | http, server, location | -| uwsgi_bind | `uwsgi_bind address [transparent];` | 绑定到特定地址 | - | http, server, location | -| uwsgi_buffering | `uwsgi_buffering on/off;` | 启用/禁用响应缓冲 | on | http, server, location | -| uwsgi_buffer_size | `uwsgi_buffer_size size;` | 设置响应缓冲区大小 | 4k/8k | http, server, location | -| uwsgi_buffers | `uwsgi_buffers number size;` | 设置缓冲区数量和大小 | 8 4k/8k | http, server, location | -| uwsgi_busy_buffers_size | `uwsgi_busy_buffers_size size;` | 设置忙缓冲区大小 | 8k/16k | http, server, location | -| uwsgi_cache | `uwsgi_cache zone;` | 启用响应缓存 | - | http, server, location | -| uwsgi_cache_key | `uwsgi_cache_key string;` | 设置缓存键 | - | http, server, location | -| uwsgi_cache_valid | `uwsgi_cache_valid time;` | 设置缓存有效期 | - | http, server, location | -| uwsgi_connect_timeout | `uwsgi_connect_timeout time;` | 连接超时 | 60s | http, server, location | -| uwsgi_send_timeout | `uwsgi_send_timeout time;` | 发送超时 | 60s | http, server, location | -| uwsgi_read_timeout | `uwsgi_read_timeout time;` | 读取超时 | 60s | http, server, location | -| uwsgi_hide_header | `uwsgi_hide_header field;` | 隐藏响应头 | - | http, server, location | -| uwsgi_pass_header | `uwsgi_pass_header field;` | 允许传递隐藏头 | - | http, server, location | -| uwsgi_ignore_client_abort | `uwsgi_ignore_client_abort on/off;` | 忽略客户端中止 | off | http, server, location | -| uwsgi_intercept_errors | `uwsgi_intercept_errors on/off;` | 拦截错误码 | off | http, server, location | - -### 2.3 配置示例 - -**基本 Django/Flask 配置:** -```nginx -location / { - include uwsgi_params; - uwsgi_pass unix:/run/uwsgi/app.sock; -} -``` - -**TCP 套接字配置:** -```nginx -location / { - include uwsgi_params; - uwsgi_pass 127.0.0.1:3031; -} -``` - -**自定义参数:** -```nginx -location / { - uwsgi_param SCRIPT_NAME /myapp; - uwsgi_param PATH_INFO $1; - uwsgi_param QUERY_STRING $query_string; - uwsgi_param REQUEST_METHOD $request_method; - uwsgi_param CONTENT_TYPE $content_type; - uwsgi_param CONTENT_LENGTH $content_length; - uwsgi_param REQUEST_URI $request_uri; - uwsgi_param DOCUMENT_ROOT $document_root; - uwsgi_param SERVER_PROTOCOL $server_protocol; - uwsgi_param HTTPS $https if_not_empty; - uwsgi_param REMOTE_ADDR $remote_addr; - uwsgi_param REMOTE_PORT $remote_port; - uwsgi_param SERVER_PORT $server_port; - uwsgi_param SERVER_NAME $server_name; - uwsgi_pass unix:/run/uwsgi/app.sock; -} -``` - -**带缓存的配置:** -```nginx -http { - uwsgi_cache_path /var/cache/nginx/uwsgi levels=1:2 keys_zone=uwsgi:10m max_size=1g; - - server { - location / { - uwsgi_cache uwsgi; - uwsgi_cache_key $host$request_uri; - uwsgi_cache_valid 200 10m; - uwsgi_cache_valid 404 1m; - include uwsgi_params; - uwsgi_pass unix:/run/uwsgi/app.sock; - } - } -} -``` - -**负载均衡配置:** -```nginx -upstream uwsgi_backend { - server 127.0.0.1:3031 weight=5; - server 127.0.0.1:3032; - server 127.0.0.1:3033 backup; - keepalive 32; -} - -location / { - include uwsgi_params; - uwsgi_pass uwsgi_backend; -} -``` - -### 2.4 与 FastCGI 的对比 - -| 特性 | uWSGI | FastCGI | -|------|-------|---------| -| 设计目标 | Python WSGI 专用 | 通用语言接口 | -| 协议开销 | 更低(二进制协议) | 较高(文本协议)| -| 性能 | 更高 | 较低 | -| 配置复杂度 | 简单 | 较复杂 | -| 语言支持 | 主要为 Python | PHP、Perl、Ruby 等 | -| 功能扩展 | 丰富的插件系统 | 有限 | -| 进程管理 | 内置多种模式 | 依赖外部管理器 | - -### 2.5 应用场景 - -1. **Django 应用部署**:高性能 Python Web 框架部署 -2. **Flask 应用部署**:轻量级 Python Web 框架部署 -3. **Python API 服务**:RESTful API 后端服务 -4. **机器学习模型服务**:部署 ML 模型推理服务 -5. **数据科学应用**:Jupyter、Streamlit 等应用托管 - ---- - -## 3. ngx_http_scgi_module (SCGI 代理) - -### 3.1 模块概述 - -ngx_http_scgi_module 模块用于将请求代理到 SCGI(Simple Common Gateway Interface)服务器。SCGI 是一种简化版的 CGI 协议,旨在提供比传统 CGI 更好的性能。 - -**主要特性:** -- 简化的 CGI 协议实现 -- 比传统 CGI 更快的性能(保持持久连接) -- 支持 Unix 域套接字和 TCP 套接字 -- 支持参数传递和环境变量设置 -- 轻量级,适合小型项目 - -### 3.2 核心指令表格 - -| 指令 | 语法 | 说明 | 默认值 | 上下文 | -|------|------|------|--------|--------| -| scgi_pass | `scgi_pass address;` | 设置 SCGI 服务器地址 | - | location, if in location | -| scgi_param | `scgi_param parameter value [if_not_empty];` | 设置传递给 SCGI 的参数 | - | http, server, location | -| scgi_bind | `scgi_bind address [transparent];` | 绑定到特定地址 | - | http, server, location | -| scgi_buffering | `scgi_buffering on/off;` | 启用/禁用响应缓冲 | on | http, server, location | -| scgi_buffer_size | `scgi_buffer_size size;` | 设置响应缓冲区大小 | 4k/8k | http, server, location | -| scgi_buffers | `scgi_buffers number size;` | 设置缓冲区数量和大小 | 8 4k/8k | http, server, location | -| scgi_busy_buffers_size | `scgi_busy_buffers_size size;` | 设置忙缓冲区大小 | 8k/16k | http, server, location | -| scgi_cache | `scgi_cache zone;` | 启用响应缓存 | - | http, server, location | -| scgi_cache_key | `scgi_cache_key string;` | 设置缓存键 | - | http, server, location | -| scgi_cache_valid | `scgi_cache_valid time;` | 设置缓存有效期 | - | http, server, location | -| scgi_connect_timeout | `scgi_connect_timeout time;` | 连接超时 | 60s | http, server, location | -| scgi_send_timeout | `scgi_send_timeout time;` | 发送超时 | 60s | http, server, location | -| scgi_read_timeout | `scgi_read_timeout time;` | 读取超时 | 60s | http, server, location | -| scgi_hide_header | `scgi_hide_header field;` | 隐藏响应头 | - | http, server, location | -| scgi_pass_header | `scgi_pass_header field;` | 允许传递隐藏头 | - | http, server, location | -| scgi_ignore_client_abort | `scgi_ignore_client_abort on/off;` | 忽略客户端中止 | off | http, server, location | -| scgi_intercept_errors | `scgi_intercept_errors on/off;` | 拦截错误码 | off | http, server, location | -| scgi_pass_request_headers | `scgi_pass_request_headers on/off;` | 传递请求头 | on | http, server, location | -| scgi_pass_request_body | `scgi_pass_request_body on/off;` | 传递请求体 | on | http, server, location | - -### 3.3 配置示例 - -**基本配置:** -```nginx -location / { - include scgi_params; - scgi_pass localhost:4000; -} -``` - -**Unix 域套接字配置:** -```nginx -location / { - include scgi_params; - scgi_pass unix:/tmp/scgi.sock; -} -``` - -**自定义参数:** -```nginx -location / { - scgi_param SCRIPT_NAME /myapp; - scgi_param PATH_INFO $1; - scgi_param QUERY_STRING $query_string; - scgi_param REQUEST_METHOD $request_method; - scgi_param CONTENT_TYPE $content_type; - scgi_param CONTENT_LENGTH $content_length; - scgi_param REQUEST_URI $request_uri; - scgi_param DOCUMENT_ROOT $document_root; - scgi_param SERVER_PROTOCOL $server_protocol; - scgi_param REMOTE_ADDR $remote_addr; - scgi_param REMOTE_PORT $remote_port; - scgi_param SERVER_PORT $server_port; - scgi_param SERVER_NAME $server_name; - scgi_pass localhost:4000; -} -``` - -**带缓存的配置:** -```nginx -http { - scgi_cache_path /var/cache/nginx/scgi levels=1:2 keys_zone=scgi:10m max_size=1g; - - server { - location / { - scgi_cache scgi; - scgi_cache_key $host$request_uri; - scgi_cache_valid 200 5m; - include scgi_params; - scgi_pass localhost:4000; - } - } -} -``` - -### 3.4 与 FastCGI/uWSGI 的对比 - -| 特性 | SCGI | FastCGI | uWSGI | -|------|------|---------|-------| -| 协议复杂度 | 简单(纯文本)| 中等 | 复杂(二进制)| -| 性能 | 中等 | 中等 | 最高 | -| 资源占用 | 低 | 中等 | 中等 | -| 连接方式 | 持久连接 | 持久连接 | 持久连接 | -| 功能丰富度 | 基础功能 | 较丰富 | 最丰富 | -| 语言支持 | 通用 | PHP 为主 | Python 为主 | -| 实现难度 | 简单 | 中等 | 复杂 | -| 适用场景 | 小型项目 | 中型项目 | 大型生产环境 | - -**SCGI vs FastCGI:** -- **SCGI**:协议更简单,实现更容易,适合轻量级应用 -- **FastCGI**:更成熟,生态更好,PHP 应用首选 - -**SCGI vs uWSGI:** -- **SCGI**:通用协议,不绑定特定语言 -- **uWSGI**:Python 专用,功能最丰富 - -### 3.5 应用场景 - -1. **小型 CGI 应用**:简单脚本语言的 Web 接口 -2. **自定义语言运行环境**:为特定语言实现 SCGI 接口 -3. **嵌入式系统**:资源受限环境下的轻量级方案 -4. **原型开发**:快速验证 Web 应用概念 -5. **学习目的**:理解 CGI 协议的简化实现 - ---- - -## 4. 三个模块对比总结 - -| 维度 | ngx_http_grpc_module | ngx_http_uwsgi_module | ngx_http_scgi_module | -|------|---------------------|----------------------|---------------------| -| **协议类型** | HTTP/2 (gRPC) | uwsgi (二进制) | SCGI (文本) | -| **主要语言** | 多语言 | Python | 多语言 | -| **性能** | 高(HTTP/2 多路复用)| 很高 | 中等 | -| **典型应用** | 微服务通信 | Django/Flask | CGI 脚本 | -| **配置复杂度** | 中等 | 简单 | 简单 | -| **功能特性** | 流、SSL、LB | 缓冲、缓存 | 基础代理 | -| **生态成熟度** | 快速增长 | 成熟(Python)| 小众 | - -## 5. 选择建议 - -- **微服务/API 网关**:选择 **grpc_module** -- **Python Web 应用**:选择 **uwsgi_module** -- **简单 CGI/轻量级**:选择 **scgi_module** 或 **fastcgi_module** - ---- - -*文档生成时间:2026-04-03* diff --git a/docs/plan.md b/docs/plan.md deleted file mode 100644 index 94c53d4..0000000 --- a/docs/plan.md +++ /dev/null @@ -1,2473 +0,0 @@ -# Lolly 实现计划 - -## 概述 - -**目标**:创建一个类似 nginx 的高性能 HTTP 服务器,纯 Go 实现,YAML 配置,单二进制运行。 - -**核心原则**: - -- 不是 1:1 复刻 nginx,而是更现代、更易用 -- 充分利用 Go 特性(goroutine、channel、标准库) -- 功能完整性优先于极致性能 -- 选择"更简单易用"的设计方案 - ---- - -## 第一阶段:项目骨架与配置系统 - -### 目标 - -搭建项目基础结构,实现配置解析和命令行工具。 - -### 任务列表 - -#### 1.1 项目目录结构 - -``` -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/ # 公共工具函数 -├── go.mod -├── go.sum -├── Makefile # 构建脚本 -└── README.md -``` - -**关键文件**: - -- `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 -v # 显示版本 -``` - -**实现方式**: - -- 使用 `flag` 标准库处理参数 -- 信号处理:`SIGTERM`、`SIGINT`、`SIGHUP` - -### 验证方法 - -```bash -# 构建测试 -make build - -# 版本显示 -./lolly -v -``` - ---- - -## 第二阶段:HTTP 核心功能 - -### 目标 - -实现基础 HTTP 服务器、静态文件服务、请求路由、基础日志系统。 - -### 技术选型 - -**HTTP 库**:使用 [fasthttp](https://github.com/valyala/fasthttp) 替代 `net/http`。 - -**选择理由**: -- **高性能**:比 net/http 快 6 倍 -- **零分配**:热点路径无内存分配,GC 压力最小 -- **原生支持高性能场景**:无需额外优化 - -**路由库**:使用 [fasthttp/router](https://github.com/fasthttp/router)。 - -**性能对比**: - -| 库 | 特点 | 性能 | -|----|------|------| -| fasthttp | 零分配,高性能 | ⭐⭐⭐⭐⭐ | -| net/http | 标准库,通用 | ⭐⭐⭐ | - -**关键差异**: - -| net/http | fasthttp | -|----------|----------| -| `http.Handler` 接口 | `RequestHandler` 函数 | -| `ServeMux` 内置路由 | 无,需 router 库 | -| `http.Request` 对象 | `*fasthttp.RequestCtx` | -| `http.ResponseWriter` | `ctx` 同时处理读写 | - -### 任务列表 - -#### 2.0 中间件框架(前置依赖) - -**实现**: - -```go -// internal/middleware/middleware.go - -import "github.com/valyala/fasthttp" - -// Middleware 中间件接口 -type Middleware interface { - Name() string - Process(next fasthttp.RequestHandler) fasthttp.RequestHandler -} - -// Chain 中间件链 -type Chain struct { - middlewares []Middleware -} - -// Apply 应用中间件链 -func (c *Chain) Apply(final fasthttp.RequestHandler) fasthttp.RequestHandler { - handler := final - for i := len(c.middlewares) - 1; i >= 0; i-- { - handler = c.middlewares[i].Process(handler) - } - return handler -} -``` - -**设计要点**: - -- 定义统一的中间件接口,所有中间件实现 `RequestHandler` 函数签名 -- 支持链式组合,按注册顺序逆序包装(从后往前) -- Phase 2 建立框架,后续阶段填充具体中间件实现 - -#### 2.1 基础 HTTP 服务器 - -**核心实现**: - -```go -// internal/server/server.go - -import "github.com/valyala/fasthttp" - -// Server HTTP 服务器 -type Server struct { - config *config.Config - fastServer *fasthttp.Server - handler fasthttp.RequestHandler - running bool -} - -// Start 启动服务器 -func (s *Server) Start() error { - s.fastServer = &fasthttp.Server{ - Handler: s.handler, - ReadTimeout: s.config.Server.ReadTimeout, - WriteTimeout: s.config.Server.WriteTimeout, - IdleTimeout: s.config.Server.IdleTimeout, - MaxConnsPerIP: s.config.Server.MaxConnsPerIP, - MaxRequestsPerConn: s.config.Server.MaxRequestsPerConn, - } - return s.fastServer.ListenAndServe(s.config.Server.Listen) -} - -// Stop 快速停止服务器 -func (s *Server) Stop() error { - return s.fastServer.Shutdown() -} - -// GracefulStop 优雅停止(等待请求完成) -func (s *Server) GracefulStop(timeout time.Duration) error { - // fasthttp 的 Shutdown 本身就是优雅关闭 - return s.fastServer.Shutdown() -} -``` - -**实现要点**: - -- 使用 `fasthttp.Server` 配置超时和连接限制 -- 优雅关闭:`Shutdown()` 方法自动等待请求完成 -- 配置项:`ReadTimeout`、`WriteTimeout`、`IdleTimeout`、`MaxConnsPerIP` - -#### 2.2 静态文件服务 - -**实现**: - -```go -// internal/handler/static.go - -import "github.com/valyala/fasthttp" - -// StaticHandler 静态文件处理器 -type StaticHandler struct { - root string - index []string -} - -// Handle 处理静态文件请求 -func (h *StaticHandler) Handle(ctx *fasthttp.RequestCtx) { - path := string(ctx.Path()) - - // 安全检查:防止目录遍历 - if strings.Contains(path, "..") { - ctx.Error("Forbidden", fasthttp.StatusForbidden) - return - } - - // 拼接文件路径 - filePath := filepath.Join(h.root, path) - - // 尝试索引文件 - if info, err := os.Stat(filePath); err == nil && info.IsDir() { - for _, idx := range h.index { - idxPath := filepath.Join(filePath, idx) - if fasthttp.ServeFile(ctx, idxPath) == nil { - return - } - } - } - - // 直接返回文件 - fasthttp.ServeFile(ctx, filePath) -} -``` - -**功能清单**: - -- 文件路径安全检查(防止目录遍历) -- MIME 类型自动识别(fasthttp 内置) -- 索引文件支持(index.html、index.htm) -- Range 请求支持(fasthttp 内置) -- 文件缓存优化(可选) - -#### 2.3 请求路由 - -**路由库**:使用 [fasthttp/router](https://github.com/fasthttp/router),基于 radix tree 高效匹配。 - -**实现**: - -```go -// internal/handler/router.go - -import ( - "github.com/valyala/fasthttp" - "github.com/fasthttp/router" -) - -// Router 请求路由器 -type Router struct { - router *router.Router -} - -// NewRouter 创建路由器 -func NewRouter() *Router { - return &Router{ - router: router.New(), - } -} - -// Register 注册路由 -func (r *Router) Register(path string, handler fasthttp.RequestHandler) { - r.router.GET(path, handler) - r.router.POST(path, handler) - r.router.PUT(path, handler) - r.router.DELETE(path, handler) -} - -// Handler 返回路由处理器 -func (r *Router) Handler() fasthttp.RequestHandler { - return r.router.Handler -} -``` - -**fasthttp/router 匹配类型**: - -| 类型 | 语法 | 示例 | -|------|------|------| -| Named | `{name}` | `/user/{id}` | -| Optional | `{name?}` | `/search/{q?}` | -| Regex | `{name:regex}` | `/user/{id:[0-9]+}` | -| Catch-All | `{filepath:*}` | `/files/{filepath:*}` | - -**参数提取**: - -```go -func handler(ctx *fasthttp.RequestCtx) { - id := ctx.UserValue("id") // 获取路由参数 -} -``` - -#### 2.4 多虚拟主机支持 - -**实现**: - -```go -// internal/server/vhost.go - -import "github.com/valyala/fasthttp" - -// VHostManager 虚拟主机管理器 -type VHostManager struct { - hosts map[string]*VirtualHost // 按 server_name 索引 - defaultHost *VirtualHost // 默认主机 -} - -// VirtualHost 虚拟主机 -type VirtualHost struct { - name string - handler fasthttp.RequestHandler -} - -// Handler 返回虚拟主机选择器 -func (v *VHostManager) Handler() fasthttp.RequestHandler { - return func(ctx *fasthttp.RequestCtx) { - host := string(ctx.Host()) - if vhost, ok := v.hosts[host]; ok { - vhost.handler(ctx) - } else if v.defaultHost != nil { - v.defaultHost.handler(ctx) - } else { - ctx.Error("Host not found", fasthttp.StatusNotFound) - } - } -} -``` - -**功能**: - -- 按 `Host` 头选择虚拟主机 -- 默认主机 fallback -- SNI 支持(SSL,Phase 4) - -#### 2.5 基础日志系统(Phase 2 必需) - -**原因**:调试 Phase 2-4 功能需要日志支持,将日志系统基础版本提前实现。 - -**选型**:使用 [zerolog](https://github.com/rs/zerolog) 作为日志库。 - -**选择理由**: -- **零分配**:高并发场景 GC 压力最小,性能最优 -- **JSON 输出**:便于日志采集系统(ELK、Loki)解析 -- **API 简洁**:链式调用风格,开发体验好 -- **灵活输出**:支持 stdout/stderr/文件,开发模式可选 ConsoleWriter 美化 - -**性能对比**(10 条日志,禁用输出): - -| 库 | ns/op | allocs/op | -|----|-------|-----------| -| zerolog | ~40ns | **0** | -| zap (structured) | ~50ns | 0 | -| slog (Go 1.21+) | ~200ns | 5+ | -| logrus | ~2000ns | 23 | - -**实现**: - -```go -// internal/logging/logging.go - -import "github.com/rs/zerolog" - -// 全局日志实例 -var log zerolog.Logger - -// Init 初始化日志系统 -func Init(level string, pretty bool) { - l := parseLevel(level) - if pretty { - // 开发模式:带颜色和格式化(性能较差,仅开发用) - log = zerolog.New(zerolog.ConsoleWriter{Out: os.Stdout}) - } else { - // 生产模式:JSON 输出 - log = zerolog.New(os.Stdout).Level(l).With().Timestamp().Logger() - } -} - -// AccessLogger 访问日志(基础版) -func LogAccess(r *http.Request, status int, size int64, duration time.Duration) { - log.Info(). - Str("method", r.Method). - Str("path", r.URL.Path). - Int("status", status). - Int64("size", size). - Dur("duration", duration). - Msg("request") -} -``` - -**Phase 2 实现范围**: - -- 基础请求日志:记录请求方法、路径、状态码 -- 控制台输出:开发阶段便于调试(ConsoleWriter 美化) -- Phase 5 将扩展为完整日志系统(文件输出、自定义格式、访问/错误日志分离) - -### 验证方法 - -```bash -# 启动服务器 -./lolly -c lolly.yaml - -# 静态文件测试 -curl http://localhost:8080/index.html - -# 路由测试 -curl http://localhost:8080/static/test.txt -curl http://localhost:8080/api/health # 应返回 404(代理未实现) -``` - ---- - -## 第三阶段:反向代理与负载均衡 - -### 目标 - -实现反向代理功能、多种负载均衡算法、健康检查。 - -### 任务列表 - -#### 3.1 反向代理核心 - -**实现**(基于 fasthttp): - -```go -// internal/proxy/proxy.go - -import "github.com/valyala/fasthttp" - -// Proxy 反向代理 -type Proxy struct { - targets []*Target - clients map[string]*fasthttp.HostClient // 每个目标一个 HostClient - balancer Balancer -} - -// Target 后端目标 -type Target struct { - URL string // 目标地址,如 "http://backend1:8080" - Weight int - Healthy bool - Connections int64 // 当前连接数(原子操作) -} - -// HostClient fasthttp 客户端(连接池) -// 每个 Target 对应一个 HostClient,自动管理连接池 -``` - -**功能清单**: - -- 请求转发:修改请求头、请求体 -- 响应处理:修改响应头 -- 超时配置:连接超时、响应超时(fasthttp.HostClient 配置) -- 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 -``` - ---- - -## 第四阶段:安全与 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/ -``` - ---- - -## 第五阶段:增强功能 - -### 目标 - -实现 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 - - 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 日志系统 - -**扩展 Phase 2 的 zerolog 实现**,增加文件输出和访问/错误日志分离。 - -**实现**: - -```go -// internal/logging/logging.go - -import ( - "io" - "github.com/rs/zerolog" -) - -// Logger 日志管理器 -type Logger struct { - accessLog zerolog.Logger // 访问日志 - errorLog zerolog.Logger // 错误日志 -} - -// New 创建日志管理器 -func New(cfg *LoggingConfig) *Logger { - // 访问日志:stdout 或文件 - accessOut := getOutput(cfg.Access.Path) - accessLog := zerolog.New(accessOut).With().Timestamp().Logger() - - // 错误日志:stderr 或文件 - errorOut := getOutput(cfg.Error.Path) - errorLevel := parseLevel(cfg.Error.Level) - errorLog := zerolog.New(errorOut).Level(errorLevel).With().Timestamp().Logger() - - return &Logger{accessLog: accessLog, errorLog: errorLog} -} - -// LogAccess 记录访问日志(nginx 格式变量) -func (l *Logger) LogAccess(r *http.Request, status int, size int64, duration time.Duration) { - l.accessLog.Info(). - Str("remote_addr", r.RemoteAddr). - Str("request", fmt.Sprintf("%s %s", r.Method, r.URL.Path)). - Int("status", status). - Int64("body_bytes_sent", size). - Dur("request_time", duration). - Msg("") -} - -// getOutput 获取输出目标(stdout/stderr/文件) -func getOutput(path string) io.Writer { - if path == "" { - return os.Stdout - } - f, _ := os.OpenFile(path, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) - return f -} -``` - -**日志格式变量**(支持 nginx 风格配置): -- `$remote_addr` - 客户端 IP -- `$request` - 请求行(方法 + 路径) -- `$status` - 响应状态码 -- `$body_bytes_sent` - 响应体大小 -- `$request_time` - 请求耗时 - -**配置示例**: - -```yaml -logging: - access: - path: /var/log/lolly/access.log # 留空则输出到 stdout - format: json # json 或 text(Phase 2 ConsoleWriter) - error: - path: /var/log/lolly/error.log # 留空则输出到 stderr - 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 -``` - ---- - -## 第六阶段:高级功能 - -### 目标 - -实现 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/ -``` - ---- - -## 文件依赖关系图 - -``` -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(可选) -``` - ---- - -## 第七阶段:功能完善 - -### 目标 - -补齐项目缺失功能,提升完整性和生产可用性。 - -### 背景分析 - -通过代码审查发现以下缺失功能: - -| 功能 | 当前状态 | 优先级 | 说明 | -|------|----------|--------|------| -| WebSocket 代理 | ⚠️ 返回 501 | P0 | 现代Web应用必备 | -| 状态监控端点 | ⚠️ 配置已有,处理器缺失 | P1 | 运维必需 | -| 代理缓存集成 | ⚠️ 缓存模块未集成 | P1 | 性能优化关键 | -| Brotli 压缩 | ⚠️ 降级为 gzip | P2 | 需引入依赖 | -| UDP Stream | ⚠️ Accept 返回 EOF | P2 | 需重写处理逻辑 | -| OCSP Stapling | ❌ 未实现 | P3 | 安全增强(可选)| - -### 任务列表 - -#### 7.1 WebSocket 代理 (P0) - -**问题**:`proxy.go:344-349` 当前返回 501 Not Implemented。 - -**实现方案**: - -```go -// internal/proxy/websocket.go - -// WebSocketBridge WebSocket 桥接器。 -type WebSocketBridge struct { - clientConn net.Conn - targetConn net.Conn -} - -// Bridge 双向转发 WebSocket 数据。 -func (b *WebSocketBridge) Bridge() error { - // 使用 io.Copy 双向转发 - // 客户端 → 后端 - // 后端 → 客户端 -} -``` - -**实现要点**: - -- 使用 `ctx.Hijack()` 获取底层 TCP 连接 -- 建立到后端的 TCP 连接 -- 发送 HTTP 升级请求 -- 启动双向 io.Copy 数据转发 -- 处理连接关闭和错误 - -**修改文件**: -- `internal/proxy/proxy.go:341-349` - 调用 WebSocket 桥接 -- 新增 `internal/proxy/websocket.go` - WebSocket 桥接逻辑 - -#### 7.2 状态监控端点 (P1) - -**问题**:`config.go:222-231` 已定义配置,但未实现处理器。 - -**实现方案**: - -```go -// internal/server/status.go - -// StatusHandler 状态监控处理器。 -type StatusHandler struct { - server *Server - allowed []net.IPNet -} - -// Status 状态响应结构。 -type Status struct { - Version string `json:"version"` - Uptime time.Duration `json:"uptime"` - Connections int64 `json:"connections"` - Requests int64 `json:"requests"` - BytesSent int64 `json:"bytes_sent"` - BytesReceived int64 `json:"bytes_received"` -} - -// ServeHTTP 返回 JSON 格式状态。 -func (h *StatusHandler) ServeHTTP(ctx *fasthttp.RequestCtx) { - // 1. 检查 IP 访问权限 - // 2. 收集状态数据 - // 3. 返回 JSON 响应 -} -``` - -**修改文件**: -- 新增 `internal/server/status.go` - 状态处理器 -- `internal/server/server.go:54,95` - 注册状态路由 - -#### 7.3 代理缓存集成 (P1) - -**问题**:`cache/file_cache.go` 已实现 `ProxyCache`,但未与代理集成。 - -**实现方案**: - -```go -// internal/proxy/proxy.go - -// Proxy 添加缓存字段。 -type Proxy struct { - // ... 现有字段 - cache *cache.ProxyCache // 新增 -} - -// ServeHTTP 集成缓存逻辑。 -func (p *Proxy) ServeHTTP(ctx *fasthttp.RequestCtx) { - // 1. 生成缓存键 - key := p.cacheKey(ctx) - - // 2. 尝试获取缓存 - if entry, ok, stale := p.cache.Get(key); ok { - // 返回缓存响应 - p.serveFromCache(ctx, entry, stale) - return - } - - // 3. 检查缓存锁(防击穿) - if waitCh := p.cache.AcquireLock(key); waitCh != nil { - <-waitCh // 等待其他请求生成缓存 - // 重新获取缓存 - } - - // 4. 请求后端 - // 5. 存入缓存 -} -``` - -**修改文件**: -- `internal/proxy/proxy.go` - 添加缓存逻辑 -- `internal/server/server.go:129-161` - 传递缓存配置 - -#### 7.4 Brotli 压缩 (P2) - -**问题**:`compression.go:209-214` 降级为 gzip。 - -**实现方案**: - -```go -// internal/middleware/compression/compression.go - -import "github.com/andybalholm/brotli" - -// compressBrotli 使用 brotli 压缩数据。 -func (m *CompressionMiddleware) compressBrotli(data []byte) []byte { - var buf bytes.Buffer - w := brotli.NewWriterLevel(&buf, m.level) - w.Write(data) - w.Close() - return buf.Bytes() -} -``` - -**实现要点**: - -- 添加依赖:`go get github.com/andybalholm/brotli` -- 添加 brotli 缓冲池 -- 更新 `compressBrotli` 方法 - -**修改文件**: -- `internal/middleware/compression/compression.go` - -#### 7.5 UDP Stream 完善 (P2) - -**问题**:`stream.go:388-391` `udpListener.Accept()` 返回 EOF。 - -**原因分析**:UDP 是数据报协议,不能像 TCP 那样 Accept 连接。 - -**实现方案**: - -```go -// internal/stream/stream.go - -// udpServer UDP 服务器。 -type udpServer struct { - conn *net.UDPConn - sessions map[string]*udpSession // 客户端地址 → 会话 - mu sync.RWMutex -} - -// udpSession UDP 会话。 -type udpSession struct { - clientAddr *net.UDPAddr - targetConn net.Conn - lastActive time.Time -} - -// serveUDP 处理 UDP 数据报。 -func (s *udpServer) serveUDP() { - buf := make([]byte, 65535) - for { - n, clientAddr, err := s.conn.ReadFromUDP(buf) - if err != nil { - continue - } - - // 查找或创建会话 - session := s.getOrCreateSession(clientAddr) - - // 转发数据到后端 - session.targetConn.Write(buf[:n]) - } -} -``` - -**修改文件**: -- `internal/stream/stream.go:199-217,383-401` - 重写 UDP 处理 - -#### 7.6 OCSP Stapling (P3 - 可选) - -**问题**:`ssl.go` 未实现 OCSP Stapling。 - -**实现方案**: - -- 在 TLS 配置中添加 `GetConfigForClient` 回调 -- 定期查询 OCSP 服务器并缓存响应 -- 在 TLS 握手中附加 OCSP 响应 - -**注意**:此功能实现复杂,可作为后续迭代项。 - -### 验证方法 - -```bash -# WebSocket 测试 -wscat -c ws://localhost:8080/ws - -# 状态监控测试 -curl http://localhost:8080/_status - -# 代理缓存测试(检查响应头) -curl -I http://localhost:8080/api/data -# 第二次请求应返回 X-Cache-Status: HIT - -# Brotli 压缩测试 -curl -H "Accept-Encoding: br" -I http://localhost:8080/index.html -# 检查 Content-Encoding: br - -# UDP Stream 测试 -dig @localhost example.com # 通过 lolly 代理 DNS -``` - -### 文件依赖关系图 - -``` -Phase 7: - internal/proxy/proxy.go → internal/proxy/websocket.go(新增) - internal/proxy/proxy.go → internal/cache/file_cache.go - internal/server/server.go → internal/server/status.go(新增) - internal/middleware/compression/compression.go → github.com/andybalholm/brotli - internal/stream/stream.go → 重写 UDP 处理 -``` - ---- - -**Phase 2 技术选型变更**: -- HTTP 库:使用 [fasthttp](https://github.com/valyala/fasthttp) 替代 `net/http`(性能提升 6 倍) -- 日志库:使用 [zerolog](https://github.com/rs/zerolog)(零分配,~40ns/op) - ---- - -## 参考文档 - -详细功能参考 `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`(必须遵循) - ---- - -## 第八阶段:问题修复与功能完善 - -### 目标 - -修复深度分析发现的三个遗留问题,提升项目生产可用性。 - -### 背景分析 - -通过代码审查发现以下问题: - -| 问题 | 当前状态 | 优先级 | 说明 | -|------|----------|--------|------| -| WebSocket 代理未集成 | ⚠️ 返回 501 | P0 | 已实现但未调用 | -| UDP Stream 冗余代码 | ⚠️ Accept 返回 EOF | P1 | 设计问题,需删除 | -| 热升级监听器继承 | ⚠️ GetListeners 返回空 | P1 | 监听器未保存 | - -### 任务列表 - -#### 8.1 WebSocket 代理集成 (P0) - -**问题**:`proxy.go:370-375` 的 `handleWebSocket` 返回 501 Not Implemented,但 `websocket.go` 中已有完整的 `ProxyWebSocket` 实现。 - -**修改文件**:`internal/proxy/proxy.go:370-375` - -**修改内容**: - -```go -// 修改前 -func (p *Proxy) handleWebSocket(ctx *fasthttp.RequestCtx, target *loadbalance.Target, client *fasthttp.HostClient) { - ctx.Error("WebSocket proxying not implemented", fasthttp.StatusNotImplemented) -} - -// 修改后 -func (p *Proxy) handleWebSocket(ctx *fasthttp.RequestCtx, target *loadbalance.Target, client *fasthttp.HostClient) { - timeout := p.config.Timeout.Connect - if timeout == 0 { - timeout = 30 * time.Second - } - if err := ProxyWebSocket(ctx, target, timeout); err != nil { - logging.Error().Msgf("WebSocket proxy error: %v", err) - } -} -``` - -#### 8.2 删除冗余 UDP 监听器 (P1) - -**问题**:`stream.go:435-453` 的 `udpListener` 类型实现 `net.Listener` 接口,但 UDP 是无连接协议,`Accept()` 始终返回 `io.EOF`。实际 UDP 处理由 `udpServer` 完成。 - -**修改文件**: -- `internal/stream/stream.go:435-453` - 删除 `udpListener` 类型 -- `internal/stream/stream_test.go` - 删除相关测试 - -**删除代码**: - -```go -// 删除以下代码(第 435-453 行) -type udpListener struct { - conn *net.UDPConn -} - -func (u *udpListener) Accept() (net.Conn, error) { - return nil, io.EOF -} - -func (u *udpListener) Close() error { - return u.conn.Close() -} - -func (u *udpListener) Addr() net.Addr { - return u.conn.LocalAddr() -} -``` - -#### 8.3 热升级监听器继承 (P1) - -**问题**: -1. `Server.listeners` 字段从未被赋值 -2. `fasthttp.ListenAndServe()` 内部创建监听器但未暴露 -3. 子进程未使用继承的监听器 - -**修改文件**: -- `internal/server/server.go` - 改用手动监听器管理 -- `internal/app/app.go` - 支持继承监听器启动 - -**核心修改**: - -```go -// server.go - 使用 net.Listen + fasthttp.Serve 替代 ListenAndServe - -// 创建监听器 -ln, err := net.Listen("tcp", s.config.Server.Listen) -if err != nil { - return fmt.Errorf("failed to listen: %w", err) -} -s.listeners = []net.Listener{ln} // 保存监听器 - -// 使用 Serve 替代 ListenAndServe -if s.tlsConfig != nil { - return s.fastServer.ServeTLS(ln, "", "") -} -return s.fastServer.Serve(ln) -``` - -```go -// app.go - 子进程继承监听器 -if os.Getenv("GRACEFUL_UPGRADE") == "1" { - fmt.Println("检测到热升级模式,继承父进程监听器") - listeners, err := a.upgradeMgr.GetInheritedListeners() - if err == nil && len(listeners) > 0 { - a.srv.SetListeners(listeners) - } -} -``` - -### 验证方法 - -```bash -# 1. WebSocket 测试 -wscat -c ws://localhost:8080/ws - -# 2. UDP Stream 测试 -go test ./internal/stream/... -v - -# 3. 热升级测试 -./lolly -c config.yaml & -kill -USR2 -# 验证新进程接管,旧进程优雅退出 - -# 4. 完整测试 -go test ./... -race -go build ./... -``` - -### 文件依赖关系图 - -``` -Phase 8: - internal/proxy/proxy.go → internal/proxy/websocket.go(调用) - internal/stream/stream.go → 删除 udpListener - internal/server/server.go → net.Listen + fasthttp.Serve - internal/app/app.go → GetInheritedListeners -``` - ---- - -## 第九阶段:HTTP/3 支持与性能优化扩展 - -### 目标 - -实现 HTTP/3 (QUIC) 协议支持,扩展负载均衡算法和限流机制,提升项目协议完整性和性能优化能力。 - -### 背景分析 - -通过与 nginx 功能对比分析,发现以下功能缺失: - -| 功能 | 当前状态 | 优先级 | 说明 | -|------|----------|--------|------| -| HTTP/3 (QUIC) | ❌ 未实现 | P0 | 新一代 HTTP 协议,性能提升 20-30% | -| 一致性哈希负载均衡 | ❌ 未实现 | P1 | 缓存代理场景关键功能 | -| gzip_static 预压缩 | ❌ 未实现 | P2 | 静态资源优化,减少 CPU 开销 | -| 滑动窗口限流 | ❌ 未实现 | P2 | 更精确的限流算法 | - -### 技术选型 - -**HTTP/3 库**:使用 [quic-go](https://github.com/quic-go/quic-go)。 - -**选择理由**: -- **官方支持**:Go 生态系统中最成熟的 QUIC 实现 -- **HTTP/3 完整实现**:支持 http3.Server,与标准库接口兼容 -- **活跃维护**:定期更新,跟进 IETF QUIC 规范 -- **性能优秀**:0-RTT、连接迁移等特性支持完善 - -**版本要求**:`github.com/quic-go/quic-go v0.48.2`(支持 Go 1.21+) - -**关键挑战**: - -| 挑战 | 说明 | 解决方案 | -|------|------|----------| -| 接口不兼容 | fasthttp 与 quic-go 接口不同 | 编写适配层转换请求格式 | -| Handler 复用 | 需让 HTTP/3 使用现有 handler 链 | adapter.go 将 http.Handler 转换为 fasthttp.RequestCtx | -| TLS 配置共享 | QUIC 内置 TLS,需复用现有证书 | 从 ssl 模块获取 tls.Config | - -### 任务列表 - -#### 9.1 HTTP/3 服务器核心 (P0) - -**实现**: - -```go -// internal/http3/server.go - -import ( - "github.com/quic-go/quic-go" - "github.com/quic-go/quic-go/http3" -) - -// Server HTTP/3 服务器。 -type Server struct { - config *config.HTTP3Config - http3Server *http3.Server - handler fasthttp.RequestHandler - adapter *Adapter -} - -// Start 启动 HTTP/3 服务器。 -func (s *Server) Start() error { - // 1. 创建 UDP 监听器 - listener, err := quic.ListenAddrEarly(s.config.Listen, s.tlsConfig, s.quicConfig) - if err != nil { - return fmt.Errorf("failed to listen QUIC: %w", err) - } - - // 2. 创建 HTTP/3 服务器 - s.http3Server = &http3.Server{ - Handler: s.adapter.Wrap(s.handler), - } - - return s.http3Server.Serve(listener) -} - -// Stop 停止 HTTP/3 服务器。 -func (s *Server) Stop() error { - if s.http3Server != nil { - return s.http3Server.Close() - } - return nil -} -``` - -**实现要点**: - -- 使用 `quic.ListenAddrEarly` 支持 0-RTT -- 复用 `internal/ssl` 模块的 TLS 配置 -- 配置 `Alt-Svc` 响应头告知客户端可用 HTTP/3 -- 支持优雅关闭 - -#### 9.2 HTTP/3 请求适配层 (P0) - -**实现**: - -```go -// internal/http3/adapter.go - -// Adapter 将 fasthttp.RequestHandler 适配为 http.Handler。 -type Adapter struct{} - -// Wrap 包装 fasthttp handler 为 http.Handler。 -func (a *Adapter) Wrap(handler fasthttp.RequestHandler) http.Handler { - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - // 1. 创建 fasthttp.RequestCtx - ctx := &fasthttp.RequestCtx{} - - // 2. 转换请求 - a.convertRequest(r, ctx) - - // 3. 调用 fasthttp handler - handler(ctx) - - // 4. 转换响应 - a.convertResponse(ctx, w) - }) -} - -// convertRequest 将 net/http.Request 转换为 fasthttp.RequestCtx。 -func (a *Adapter) convertRequest(r *http.Request, ctx *fasthttp.RequestCtx) { - // 方法 - ctx.Request.Header.SetMethod(r.Method) - - // URI - ctx.Request.SetRequestURI(r.URL.String()) - - // 头部 - for k, v := range r.Header { - for _, vv := range v { - ctx.Request.Header.Add(k, vv) - } - } - - // 请求体 - if r.Body != nil { - body, _ := io.ReadAll(r.Body) - ctx.Request.SetBody(body) - } - - // 远程地址 - ctx.SetRemoteAddr(r.RemoteAddr) -} - -// convertResponse 将 fasthttp.RequestCtx 响应写入 http.ResponseWriter。 -func (a *Adapter) convertResponse(ctx *fasthttp.RequestCtx, w http.ResponseWriter) { - // 状态码 - w.WriteHeader(ctx.Response.StatusCode()) - - // 头部 - ctx.Response.Header.VisitAll(func(k, v []byte) { - w.Header().Add(string(k), string(v)) - }) - - // 响应体 - w.Write(ctx.Response.Body()) -} -``` - -**性能优化**: - -- 使用 sync.Pool 复用 RequestCtx 对象 -- 避免不必要的内存分配 -- 流式处理大请求体 - -#### 9.3 一致性哈希负载均衡 (P1) - -**实现**: - -```go -// internal/loadbalance/consistent_hash.go - -// ConsistentHash 一致性哈希负载均衡器。 -type ConsistentHash struct { - // virtualNodes 虚拟节点数,默认 150 - virtualNodes int - - // circle 哈希环,key 为哈希值,value 为目标 - circle map[uint64]*Target - - // sortedHashes 排序后的哈希值列表,用于二分查找 - sortedHashes []uint64 - - // hashKey 哈希键来源 - hashKey string // "ip", "uri", "header:xxx" - - // mu 读写锁 - mu sync.RWMutex -} - -// Select 根据哈希键选择目标。 -func (c *ConsistentHash) Select(targets []*Target) *Target { - return c.SelectByKey(targets, "") -} - -// SelectByKey 根据指定键选择目标。 -func (c *ConsistentHash) SelectByKey(targets []*Target, key string) *Target { - c.mu.RLock() - defer c.mu.RUnlock() - - // 1. 计算键的哈希值 - hash := c.hashKey(key) - - // 2. 二分查找最近的节点 - idx := sort.Search(len(c.sortedHashes), func(i int) bool { - return c.sortedHashes[i] >= hash - }) - - // 3. 环形回绕 - if idx >= len(c.sortedHashes) { - idx = 0 - } - - return c.circle[c.sortedHashes[idx]] -} - -// AddTarget 添加目标到哈希环。 -func (c *ConsistentHash) AddTarget(target *Target) { - c.mu.Lock() - defer c.mu.Unlock() - - for i := 0; i < c.virtualNodes; i++ { - key := fmt.Sprintf("%s#%d", target.URL, i) - hash := c.hashKey(key) - c.circle[hash] = target - c.sortedHashes = append(c.sortedHashes, hash) - } - - sort.Slice(c.sortedHashes, func(i, j int) bool { - return c.sortedHashes[i] < c.sortedHashes[j] - }) -} - -// hashKey 计算哈希值(使用 FNV-64a)。 -func (c *ConsistentHash) hashKey(key string) uint64 { - h := fnv.New64a() - h.Write([]byte(key)) - return h.Sum64() -} -``` - -**配置示例**: - -```yaml -proxy: - - path: /api - targets: - - url: http://backend1:8080 - - url: http://backend2:8080 - - url: http://backend3:8080 - load_balance: consistent_hash - hash_key: ip # ip / uri / header:X-User-ID - virtual_nodes: 150 -``` - -#### 9.4 gzip_static 预压缩支持 (P2) - -**实现**: - -```go -// internal/middleware/compression/gzip_static.go - -// GzipStatic 预压缩文件支持。 -type GzipStatic struct { - // enabled 是否启用 - enabled bool - - // root 静态文件根目录 - root string - - // extensions 支持的扩展名 - extensions []string // 默认 [".html", ".css", ".js", ".json", ".xml"] -} - -// ServeFile 发送预压缩文件(如果存在)。 -func (g *GzipStatic) ServeFile(ctx *fasthttp.RequestCtx, filePath string) bool { - if !g.enabled { - return false - } - - // 1. 检查客户端是否支持 gzip - if !bytes.Contains(ctx.Request.Header.Peek("Accept-Encoding"), []byte("gzip")) { - return false - } - - // 2. 检查扩展名 - if !g.matchExtension(filePath) { - return false - } - - // 3. 检查预压缩文件是否存在 - gzPath := filePath + ".gz" - if _, err := os.Stat(filepath.Join(g.root, gzPath)); err != nil { - return false - } - - // 4. 发送预压缩文件 - ctx.Response.Header.Set("Content-Encoding", "gzip") - ctx.Response.Header.Set("Vary", "Accept-Encoding") - fasthttp.ServeFile(ctx, filepath.Join(g.root, gzPath)) - return true -} -``` - -**配置示例**: - -```yaml -compression: - gzip_static: on # on / off - gzip_static_extensions: [".html", ".css", ".js", ".json", ".xml", ".svg"] -``` - -**与现有压缩中间件集成**: - -```go -// compression.go 中添加预压缩检查 -func (m *CompressionMiddleware) Process(next fasthttp.RequestHandler) fasthttp.RequestHandler { - return func(ctx *fasthttp.RequestCtx) { - // 1. 尝试发送预压缩文件 - if m.gzipStatic.ServeFile(ctx, string(ctx.Path())) { - return - } - - // 2. 回退到实时压缩 - // ... 现有逻辑 - } -} -``` - -#### 9.5 滑动窗口限流算法 (P2) - -**实现**: - -```go -// internal/middleware/security/sliding_window.go - -// SlidingWindowLimiter 滑动窗口限流器。 -type SlidingWindowLimiter struct { - // window 窗口大小 - window time.Duration - - // limit 窗口内最大请求数 - limit int - - // precise 是否使用精确模式 - precise bool - - // counters 窗口计数器,key 为窗口起始时间 - counters map[int64]*windowCounter - - // mu 读写锁 - mu sync.RWMutex -} - -// windowCounter 窗口计数器。 -type windowCounter struct { - count int64 - // precise 模式下记录每个请求时间 - timestamps []time.Time -} - -// Allow 检查是否允许请求。 -func (s *SlidingWindowLimiter) Allow(key string) bool { - if s.precise { - return s.allowPrecise(key) - } - return s.allowApproximate(key) -} - -// allowApproximate 近似滑动窗口(推荐,内存 O(1))。 -func (s *SlidingWindowLimiter) allowApproximate(key string) bool { - s.mu.Lock() - defer s.mu.Unlock() - - now := time.Now() - currentWindow := now.UnixNano() / int64(s.window) - prevWindow := currentWindow - 1 - - // 获取当前窗口计数 - current, ok := s.counters[currentWindow] - if !ok { - current = &windowCounter{} - s.counters[currentWindow] = current - } - - // 获取上一个窗口计数 - prev, ok := s.counters[prevWindow] - - // 计算滑动窗口内的请求数 - // 公式:当前窗口计数 × 1.0 + 上一窗口计数 × (1 - 当前窗口已过比例) - var count int64 - if ok { - elapsed := float64(now.UnixNano()%int64(s.window)) / float64(s.window) - count = current.count + int64(float64(prev.count)*(1-elapsed)) - } else { - count = current.count - } - - if count >= int64(s.limit) { - return false - } - - current.count++ - return true -} - -// allowPrecise 精确滑动窗口(内存 O(n),精确限流)。 -func (s *SlidingWindowLimiter) allowPrecise(key string) bool { - s.mu.Lock() - defer s.mu.Unlock() - - now := time.Now() - windowStart := now.Add(-s.window) - - // 清理过期的时间戳 - valid := make([]time.Time, 0, len(s.timestamps)) - for _, t := range s.timestamps { - if t.After(windowStart) { - valid = append(valid, t) - } - } - s.timestamps = valid - - // 检查是否超过限制 - if len(s.timestamps) >= s.limit { - return false - } - - s.timestamps = append(s.timestamps, now) - return true -} -``` - -**配置示例**: - -```yaml -security: - rate_limit: - request_rate: 100 - burst: 20 - algorithm: sliding_window # token_bucket / sliding_window - sliding_window_mode: approximate # approximate / precise -``` - -#### 9.6 配置扩展 - -**新增配置结构**: - -```go -// internal/config/config.go - -// HTTP3Config HTTP/3 配置。 -type HTTP3Config struct { - Enabled bool `yaml:"enabled"` // 是否启用 HTTP/3 - Listen string `yaml:"listen"` // UDP 监听地址,如 ":443" - MaxStreams int `yaml:"max_streams"` // 最大并发流 - IdleTimeout time.Duration `yaml:"idle_timeout"` // 空闲超时 - Enable0RTT bool `yaml:"enable_0rtt"` // 启用 0-RTT -} - -// LoadBalanceConfig 负载均衡扩展配置。 -type LoadBalanceConfig struct { - HashKey string `yaml:"hash_key"` // 一致性哈希键:ip / uri / header:xxx - VirtualNodes int `yaml:"virtual_nodes"` // 虚拟节点数,默认 150 -} - -// CompressionConfig 扩展。 -type CompressionConfig struct { - // ... 现有字段 - GzipStatic bool `yaml:"gzip_static"` // 启用预压缩 - GzipStaticExtensions []string `yaml:"gzip_static_extensions"` // 预压缩扩展名 -} - -// RateLimitConfig 扩展。 -type RateLimitConfig struct { - // ... 现有字段 - Algorithm string `yaml:"algorithm"` // token_bucket / sliding_window - SlidingWindowMode string `yaml:"sliding_window_mode"` // approximate / precise -} -``` - -#### 9.7 app.go 集成 - -**修改文件**:`internal/app/app.go` - -**修改内容**: - -```go -// Run 启动应用(修改后)。 -func (a *App) Run() error { - // 1. 启动 TCP Server (HTTP/1.1/2) - go func() { - if err := a.srv.Start(); err != nil { - logging.Error().Msgf("HTTP server error: %v", err) - } - }() - - // 2. 如果启用 HTTP/3,启动 UDP Server - if a.config.HTTP3.Enabled { - go func() { - if err := a.http3Server.Start(); err != nil { - logging.Error().Msgf("HTTP/3 server error: %v", err) - } - }() - } - - // 3. 如果配置了 Stream,启动 Stream Server - // ... 现有逻辑 - - return nil -} - -// Shutdown 关闭应用(修改后)。 -func (a *App) Shutdown() error { - var errs []error - - // 关闭 HTTP/3 Server - if a.http3Server != nil { - if err := a.http3Server.Stop(); err != nil { - errs = append(errs, err) - } - } - - // 关闭 TCP Server - if err := a.srv.Stop(); err != nil { - errs = append(errs, err) - } - - // ... 其他关闭逻辑 - - if len(errs) > 0 { - return fmt.Errorf("shutdown errors: %v", errs) - } - return nil -} -``` - -### 验证方法 - -```bash -# 1. HTTP/3 测试 -# 启动服务器(配置 http3.enabled: true) -./lolly -c config.yaml - -# 使用 curl 测试 HTTP/3 -curl --http3 https://localhost:8443/ - -# 检查 Alt-Svc 头 -curl -I https://localhost:8443/ -# 应返回 Alt-Svc: h3=":443" - -# 2. 一致性哈希测试 -# 配置 load_balance: consistent_hash -for i in {1..10}; do - curl http://localhost:8080/api/test -done -# 相同 IP 的请求应路由到同一后端 - -# 3. gzip_static 测试 -# 创建预压缩文件 -gzip -k static/index.html - -# 测试请求 -curl -H "Accept-Encoding: gzip" -I http://localhost:8080/index.html -# 应返回 Content-Encoding: gzip,且响应时间更快 - -# 4. 滑动窗口限流测试 -# 配置 algorithm: sliding_window -for i in {1..120}; do - curl http://localhost:8080/ -done -# 应有部分请求返回 429 - -# 5. 完整测试 -go test ./... -race -go build ./... -``` - -### 文件依赖关系图 - -``` -Phase 9: - internal/http3/server.go → internal/http3/adapter.go(新增) - internal/http3/server.go → internal/ssl/ssl.go(TLS 配置复用) - internal/app/app.go → internal/http3/server.go(集成) - - internal/loadbalance/balancer.go → internal/loadbalance/consistent_hash.go(新增) - - internal/middleware/compression/compression.go → internal/middleware/compression/gzip_static.go(新增) - - internal/middleware/security/ratelimit.go → internal/middleware/security/sliding_window.go(新增) - - internal/config/config.go → 扩展配置结构 -``` - ---- - -## 总体进度追踪(更新) - -| 阶段 | 状态 | 主要功能 | -| ------- | -------- | ------------------------- | -| Phase 1 | ✅ 完成 | 项目骨架、配置系统 | -| Phase 2 | ✅ 完成 | HTTP 核心、静态文件、路由 | -| Phase 3 | ✅ 完成 | 反向代理、负载均衡 | -| Phase 4 | ✅ 完成 | SSL/TLS、安全控制 | -| Phase 5 | ✅ 完成 | 重写、压缩、缓存、日志 | -| Phase 6 | ✅ 完成 | Stream、性能优化、热升级 | -| Phase 7 | ✅ 完成 | 功能完善 | -| Phase 8 | ✅ 完成 | 问题修复(WebSocket集成、UDP清理、热升级修复)| -| Phase 9 | 🔄 计划中| HTTP/3、一致性哈希、gzip_static、滑动窗口限流 | - -**Phase 8 完成日期**:2026-04-03 - -**修复内容**: -1. WebSocket 代理集成 - `handleWebSocket` 现调用 `ProxyWebSocket` -2. UDP Stream 冗余代码 - 删除 `udpListener` 类型及相关测试 -3. 热升级监听器继承 - 改用 `net.Listen` + `Serve` 模式,支持监听器继承 - -**Phase 9 计划内容**: -1. HTTP/3 (QUIC) 支持 - 使用 quic-go,双栈并行架构 -2. 一致性哈希负载均衡 - 支持可配置哈希键(ip/uri/header) -3. gzip_static 预压缩 - 静态资源优化 -4. 滑动窗口限流 - 近似和精确两种模式 diff --git a/docs/prompts.md b/docs/prompts.md deleted file mode 100644 index 33bbf1a..0000000 --- a/docs/prompts.md +++ /dev/null @@ -1,322 +0,0 @@ -# Lolly 项目需求文档 - -> 本文档用于指导 AI 实现一个高性能 HTTP 服务器项目。 - -## 一、项目定位 - -创建一个类似 nginx 的高性能 HTTP 服务器,项目名称为 **lolly**。 - -### 核心目标 - -- 实现与 nginx 相同的核心功能,但**不是 1:1 复刻** -- 比 nginx 更加现代、更加易用 -- 充分利用 Go 语言特性(goroutine、channel、标准库等) -- 保持高性能(高并发、低内存消耗) - -### 技术约束 - -| 约束项 | 要求 | -|--------|------| -| 语言 | 纯 Go 实现,不依赖 C 库 | -| 部署 | 静态链接,单二进制文件即可运行 | -| 配置 | YAML 格式(比 nginx 的 nginx.conf 更简单易用) | -| 兼容性 | 跨平台支持(Linux、macOS、Windows) | - ---- - -## 二、功能需求 - -### 必须实现的核心功能(参考 docs/ 目录详细文档) - -#### 2.1 HTTP 核心模块(优先级:最高) - -参考:`docs/03-nginx-http-core.md` - -- **Server/Location 配置**:虚拟主机、请求路由 -- **静态文件服务**:高效 serving 静态资源 -- **请求处理**:请求头、请求体、超时控制 -- **keep-alive**:长连接支持 -- **MIME 类型**:自动识别内容类型 - -#### 2.2 反向代理与负载均衡(优先级:高) - -参考:`docs/04-nginx-proxy-loadbalancing.md` - -- **反向代理**:proxy_pass 功能 -- **负载均衡算法**:轮询、权重、最少连接、IP 哈希 -- **健康检查**:主动/被动健康检测 -- **WebSocket 支持**:Upgrade 协议处理 -- **代理缓存**:响应缓存机制 - -#### 2.3 SSL/TLS 与 HTTPS(优先级:高) - -参考:`docs/05-nginx-ssl-https.md` - -- **HTTPS 服务**:证书配置 -- **SSL 会话缓存**:减少握手开销 -- **HTTP/2 支持**:现代化协议 -- **自动证书管理**:可选 ACME/Let's Encrypt 集成 - -#### 2.4 URL 重写与请求处理(优先级:中) - -参考:`docs/06-nginx-rewrite.md` - -- **URL 重写**:灵活的路由规则 -- **重定向**:301/302 等状态码 -- **请求修改**:添加/修改请求头 - -#### 2.5 压缩与缓存(优先级:中) - -参考:`docs/07-nginx-compression-caching.md` - -- **Gzip/Brotli 压缩**:响应压缩 -- **静态文件缓存**:文件描述符缓存 -- **代理响应缓存**:缓存代理请求结果 - -#### 2.6 日志与监控(优先级:中) - -参考:`docs/08-nginx-logging-monitoring.md` - -- **访问日志**:可定制日志格式 -- **错误日志**:分级日志 -- **状态监控**:实时状态端点(类似 stub_status) -- **日志轮转**:内置支持 - -#### 2.7 安全与访问控制(优先级:高) - -参考:`docs/09-nginx-security.md` - -- **IP 访问控制**:白名单/黑名单 -- **请求限制**:速率限制、连接限制 -- **安全头部**:自动添加安全相关 HTTP 头 -- **基础认证**:Basic Auth 支持 - -#### 2.8 TCP/UDP Stream 代理(优先级:低) - -参考:`docs/10-nginx-stream-tcp-udp.md` - -- **TCP 代理**:四层代理支持 -- **UDP 代理**:UDP 流处理 -- **Stream 负载均衡**:四层负载均衡 - -#### 2.9 邮件代理(优先级:最低,可选) - -参考:`docs/11-nginx-mail-proxy.md` - -- IMAP/POP3/SMTP 代理(可后期实现或不实现) - ---- - -## 三、配置文件设计 - -### 设计原则 - -配置文件采用 YAML 格式,设计原则: - -1. **简洁易用**:比 nginx.conf 更直观 -2. **结构清晰**:层级明确,易于理解 -3. **类型安全**:配置值有明确类型 -4. **默认合理**:开箱即用,最小配置即可运行 - -### 配置文件示例(仅供参考) - -```yaml -# lolly.yaml - 最简配置示例 -server: - listen: 8080 - name: example.com - - # 静态文件服务 - static: - root: /var/www/html - index: [index.html, index.htm] - - # 反向代理 - proxy: - - path: /api - target: http://backend:8080 - load_balance: round_robin - - # SSL/HTTPS - ssl: - cert: /etc/ssl/cert.pem - key: /etc/ssl/key.pem - -# 日志配置 -logging: - access: /var/log/lolly/access.log - error: /var/log/lolly/error.log - level: info - -# 性能配置 -performance: - workers: auto # 自动匹配 CPU 核心数 - max_connections: 10000 - keepalive_timeout: 60s -``` - -### 配置与 nginx 的对比 - -| nginx 配置 | lolly 配置(预期) | -|------------|-------------------| -| `worker_processes auto;` | `performance.workers: auto` | -| `listen 80;` | `server.listen: 80` | -| `root /var/www;` | `server.static.root: /var/www` | -| `proxy_pass http://backend;` | `server.proxy.target: http://backend` | -| `ssl_certificate cert.pem;` | `server.ssl.cert: cert.pem` | - ---- - -## 四、架构设计要求 - -### 4.1 Go 特性利用 - -充分利用 Go 语言特性: - -- **Goroutine**:每个连接一个 goroutine,天然高并发 -- **Channel**:进程内通信、信号处理 -- **标准库**:`net/http`、`net`、`io`、`sync` 等 -- **Context**:请求超时控制、取消传播 -- **接口**:模块化设计,接口抽象 - -### 4.2 模块化设计 - -``` -lolly/ -├── cmd/ -│ └── lolly/ -│ └── main.go # 入口 -├── internal/ -│ ├── config/ # 配置解析 -│ ├── server/ # HTTP 服务器核心 -│ ├── proxy/ # 反向代理 -│ ├── loadbalance/ # 负载均衡算法 -│ ├── ssl/ # SSL/TLS 支持 -│ ├── rewrite/ # URL 重写 -│ ├── cache/ # 缓存模块 -│ ├── compression/ # 压缩模块 -│ ├── logging/ # 日志模块 -│ ├── security/ # 安全模块 -│ ├── stream/ # TCP/UDP 代理 -│ └── middleware/ # 中间件系统 -├── pkg/ -│ └── utils/ # 公共工具 -└── configs/ - └── lolly.yaml # 默认配置 -``` - -### 4.3 性能要求 - -- 单机支持数万并发连接 -- 低内存消耗(相比 nginx 同等功能) -- 静态文件高效传输(利用 `sendfile` 等优化) -- 连接复用、缓冲池 - ---- - -## 五、开发规范 - -### 5.1 提交规范 - -每完成一个功能点提交一次,提交格式遵循最佳实践: - -``` -(): - - - -