Files
asd-backend/IMPROVEMENTS.md
Milky0217 741d6acff1 feat: 升级日志系统为 tracing 结构化日志
- 替换 env_logger 为 tracing + tracing-subscriber
- 统一使用 tracing::{debug, error, info, warn} 日志宏
- 消除所有 eprintln!/println 调用
- 添加 JSON 格式日志输出便于 ELK Stack 收集
- 添加文件日志轮转(每天一个新文件 ./logs/rust-backend-{date}.log)
- 日志等级过滤:rust_backend=info, actix_web=info, sqlx=warn
- 更新 IMPROVEMENTS.md 标记 6.1 日志系统两项完成
2026-04-15 10:39:30 +08:00

538 lines
15 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Rust 后端 - 改进计划
## 一、代码质量与架构改进
### 1.1 代码组织问题
- [ ] **所有路由处理器都在 main.rs 中**
- 现状:`main.rs` 包含所有路由处理器文件过大800+ 行)
- 改进:按功能模块拆分到独立文件
- `handlers/auth.rs` - 登录相关
- `handlers/weather.rs` - 天气数据相关
- `handlers/user.rs` - 用户相关
- `handlers/admin.rs` - 管理员相关
- 影响:提高代码可维护性
- [ ] **config.rs 是死代码**
- 现状AGENTS.md 中提到 config.rs 未被使用
- 改进:要么启用配置管理,要么删除该文件
- 影响:减少代码混淆
### 1.2 数据库操作优化
- [ ] **重复查询问题**
- 位置:`insert_weather_data` 中多次查询用户信息
- 改进:合并查询或使用缓存
- 影响:减少数据库负载
- [ ] **缺少数据库索引**
- 现状:未见索引定义
- 改进:添加常用查询字段索引
```sql
CREATE INDEX idx_weather_data_user_id ON weather_data(user_id);
CREATE INDEX idx_weather_data_date ON weather_data(date);
CREATE INDEX idx_users_openid ON users(openid);
```
### 1.3 错误处理改进
- [ ] **错误响应格式不统一**
- 现状:部分返回 `ErrorResponse`,部分返回 JSON 字符串
- 改进:统一使用 `ErrorResponse` 结构体
- 彰响:前端解析更一致
- [ ] **错误信息暴露过多**
- 现状:部分错误直接返回数据库错误信息
- 改进:区分用户友好错误和开发者错误
- 影响:安全性提升
## 二、安全性改进
### 2.1 认证安全
- [ ] **缺少请求频率限制**
- 风险API 可能被滥用或遭受暴力攻击
- 改进:添加 Rate Limiting 中间件
- 实现:使用 `actix-limitation` 或自定义中间件
- 配置:
- 登录接口5 次/分钟
- 数据上传30 次/分钟
- 查询接口100 次/分钟
- [ ] **缺少 CSRF 防护**
- 风险:跨站请求伪造攻击
- 改进:添加 CSRF Token 验证
- 实现:对于状态变更操作验证 Token
- [ ] **JWT Secret 管理**
- 现状:明文存储在环境变量
- 改进:使用密钥管理服务(如 AWS Secrets Manager
- 影响:提高密钥安全性
### 2.2 数据安全
- [ ] **数据库连接字符串明文存储**
- 位置:`.env` 文件
- 改进:使用连接字符串加密或密钥管理
- 影响:防止凭证泄露
- [ ] **缺少敏感数据加密**
- 现状:用户信息明文存储
- 改进:对敏感字段加密存储
- 字段:手机号、姓名等
- [ ] **缺少审计日志**
- 需求:记录关键操作日志
- 实现:添加审计日志表和中间件
- 记录:登录、数据修改、管理员操作
### 2.3 输入验证
- [ ] **后端输入验证不完整**
- 现状:部分依赖前端验证
- 改进:添加完整的请求验证
- 实现:使用 `validator` crate
## 三、性能优化
### 3.1 数据库性能
- [ ] **缺少连接池监控**
- 现状:连接池配置固定
- 改进:添加连接池监控和动态调整
- 指标:连接数、等待时间、超时次数
- [ ] **缺少查询缓存**
- 场景:用户信息、配置数据
- 改进:添加 Redis 缓存层
- 策略:用户信息缓存 5 分钟,配置数据缓存 1 小时
- [ ] **无读写分离支持**
- 需求:高并发场景下的性能优化
- 改进:支持主从数据库配置
- 实现:使用 sqlx 的多数据源支持
### 3.2 API 性能
- [ ] **无响应压缩**
- 现状:响应未压缩
- 改进:添加 gzip 压缩中间件
- 实现:使用 `actix-web` 的压缩功能
- [ ] **缺少 API 缓存**
- 场景:天气数据列表查询
- 改进:添加 HTTP 缓存头
- 实现:`Cache-Control`、`ETag` 等
- [ ] **无 CDN 支持**
- 场景:静态资源分发
- 改进:配置 CDN 加速
- 资源CSS、JS、图片、字体
## 四、功能完整性改进
### 4.1 API 功能扩展
- [ ] **缺少批量操作接口**
- 需求:批量删除、批量查询
- 实现:添加批量操作端点
- 接口:`POST /weather/batch-delete`、`POST /weather/batch-query`
- [ ] **无数据导出格式支持**
- 需求:支持 CSV、Excel 导出
- 实现:添加导出端点
- 接口:`GET /weather/export?format=csv`
- [ ] **缺少搜索和过滤功能**
- 需求:按日期、标题、地点搜索
- 实现:添加搜索参数
- 参数:`?keyword=xxx&startDate=xxx&endDate=xxx`
### 4.2 用户功能
- [ ] **缺少用户活动统计**
- 需求:用户使用情况分析
- 实现:添加统计接口
- 数据:登录次数、数据上传量、最后活跃时间
- [ ] **无用户偏好设置**
- 需求:保存用户偏好(如默认区域类型)
- 实现:添加用户设置表
- 接口:`GET/PUT /api/user/preferences`
## 五、开发体验改进
### 5.1 测试覆盖
- [ ] **仅有一个基础编译测试**
- 现状:`tests/integration_test.rs` 只有 `assert_eq!(2 + 2, 4)`
- 改进:添加完整的测试套件
- 类型:
- 单元测试:工具函数、数据结构
- 集成测试API 端点
- 数据库测试CRUD 操作
- [ ] **缺少 API 测试**
- 需求:验证 API 行为
- 实现:使用 `actix-web` 的测试工具
- 覆盖:正常流程、异常情况、边界条件
### 5.2 文档完善
- [ ] **无 API 文档**
- 需求:接口文档
- 实现:使用 OpenAPI/Swagger
- 工具:`utoipa` crate
- [ ] **缺少部署文档**
- 内容:环境要求、配置说明、部署步骤
- 形式:`DEPLOYMENT.md` 文件
- [ ] **无变更日志**
- 内容:版本更新记录
- 形式:`CHANGELOG.md` 文件
### 5.3 开发工具
- [ ] **缺少代码质量工具**
- 工具:`clippy`、`rustfmt`
- 配置:`.clippy.toml`、`rustfmt.toml`
- 集成CI/CD 流程
- [ ] **无热重载开发**
- 需求:开发时自动重载
- 实现:使用 `cargo-watch`
- 命令:`cargo watch -x run`
## 六、监控与运维
### 6.1 日志系统
- [x] **日志格式不统一** ✅
- 现状:部分使用 `log` 宏,部分使用 `println`
- 改进:统一使用结构化日志
- 实现:使用 `tracing` crate
- 完成时间2026-04-15
- 修改文件Cargo.toml, src/main.rs, src/config.rs
- [ ] **无日志聚合**
- 需求:集中式日志管理
- 实现:配置日志收集器(如 ELK Stack
- 格式JSON 格式便于解析
- 状态:✅ 已完成JSON + 文件轮转2026-04-15
- [ ] **缺少性能指标收集**
- 需求API 响应时间、错误率等
- 实现:添加 Prometheus 指标
- 工具:`actix-web-prom`
### 6.2 告警机制
- [ ] **无异常告警**
- 需求:系统异常时通知
- 实现:集成告警服务
- 渠道:邮件、钉钉、企业微信
- [ ] **缺少资源监控**
- 需求CPU、内存、磁盘监控
- 实现:使用系统监控工具
- 工具Prometheus + Grafana
### 6.3 健康检查
- [ ] **缺少健康检查接口**
- 需求:负载均衡器健康检查
- 实现:添加 `/health` 端点
- 检查:数据库连接、服务状态
## 七、部署改进
### 7.1 部署流程
- [ ] **部署脚本功能简单**
- 现状:仅支持基本的编译、上传、重启
- 改进:添加回滚、备份、验证功能
- 实现:增强 `deploy.sh` 脚本
- [ ] **无蓝绿部署或滚动更新**
- 需求:零停机部署
- 实现:使用 Docker + Kubernetes
- 或者Nginx 负载均衡 + 多实例
### 7.2 容器化
- [ ] **缺少 Docker 支持**
- 需求:容器化部署
- 实现:添加 `Dockerfile` 和 `docker-compose.yml`
- 优势:环境一致性、易于扩展
### 7.3 CI/CD
- [ ] **无自动化流程**
- 需求:自动测试、构建、部署
- 实现:配置 GitHub Actions 或 Gitea Actions
- 流程:代码提交 → 测试 → 构建 → 部署
## 八、技术债务
### 8.1 高优先级
1. [ ] **拆分 main.rs 中的路由处理器**
- 影响:代码可维护性
- 工作量:中等
2. [ ] **添加请求频率限制**
- 影响:安全性
- 工作量:小
3. [ ] **统一错误响应格式**
- 影响:前后端对接
- 工作量:小
4. [ ] **添加数据库索引**
- 影响:性能
- 工作量:小
### 8.2 中优先级
1. [ ] **添加单元测试和集成测试**
- 影响:代码质量
- 工作量:大
2. [ ] **实现 API 文档OpenAPI**
- 影响:开发体验
- 工作量:中等
3. [ ] **添加结构化日志**
- 影响:运维
- 工作量:中等
4. [ ] **优化数据库查询**
- 影响:性能
- 工作量:中等
### 8.3 低优先级
1. [ ] **实现 Redis 缓存**
- 影响:性能
- 工作量:大
2. [ ] **容器化部署**
- 影响:部署流程
- 工作量:中等
3. [ ] **添加监控告警**
- 影响:运维
- 工作量:大
4. [ ] **实现 CI/CD**
- 影响:开发效率
- 工作量:中等
## 十、缺少环境区分机制
### 问题描述
当前后端项目未区分生产环境和开发/测试环境,所有配置混在一个 `.env` 文件中。
**现状分析**
| 配置项 | 当前做法 | 问题 |
|--------|----------|------|
| DATABASE_URL | 硬编码生产数据库地址 | 开发/测试时无法切换到本地或测试数据库 |
| JWT_SECRET | 混在 .env 中 | 开发环境使用弱密钥存在安全隐患 |
| RUST_LOG | 统一设置为 `info` | 开发时需要 `debug` 级别日志 |
| APP_VERSION | 在 .env 和 Cargo.toml 两处定义 | 版本不一致 |
**.env 当前内容**
```bash
DATABASE_URL=postgres://milkydata:***@154.37.213.24:5432/milkydata
WECHAT_APPID="wx5b00eb90621802f7"
WECHAT_SECRET="494efc...9bfd"
JWT_SECRET="your_s..._key"
SSL_KEY_PATH=/etc/ssl/private/private.key
SSL_CERT_PATH=/etc/ssl/certs/full_chain.pem
RUST_LOG=info
APP_VERSION="0.2.0"
FREE_USER_DATA_LIMIT=20
```
### 影响
- 开发时连接生产数据库,有误操作风险
- 测试时无法使用独立的测试数据
- 切换环境需要手动修改配置,容易出错
- 生产配置泄露到代码仓库(.env 通常被 gitignore但部署时容易混淆
### 解决方案
#### 方案一:使用 config crate推荐
**添加依赖**
```toml
# Cargo.toml
[dependencies]
config = "0.14"
serde = { version = "1.0", features = ["derive"] }
```
**目录结构**
```
rust-backend/
├── config/
│ ├── default.toml # 默认配置(开发)
│ ├── development.toml
│ └── production.toml
├── .env # 本地敏感配置(加入 .gitignore
└── .env.example # 配置模板(提交到仓库)
```
**default.toml开发/测试默认)**
```toml
database_url = "postgres://milkydata:password@localhost:5432/milkydata_dev"
wechat_appid = "wx_test_appid"
wechat_secret = "test_secret"
jwt_secret = "dev-only-secret-change-in-production"
ssl_key_path = ""
ssl_cert_path = ""
rust_log = "debug"
app_version = "0.2.3"
environment = "development"
free_user_data_limit = 100
server_host = "0.0.0.0"
server_port = 8080
```
**production.toml生产环境**
```toml
database_url = "postgres://milkydata:***@154.37.213.24:5432/milkydata"
wechat_appid = "wx5b00eb90621802f7"
wechat_secret = "***"
jwt_secret = "***"
ssl_key_path = "/etc/ssl/private/private.key"
ssl_cert_path = "/etc/ssl/certs/full_chain.pem"
rust_log = "info"
app_version = "0.2.3"
environment = "production"
free_user_data_limit = 20
server_host = "0.0.0.0"
server_port = 8080
```
**配置加载逻辑**
```rust
// src/config.rs
use config::{Config, ConfigError, File};
use serde::Deserialize;
#[derive(Debug, Deserialize, Clone)]
pub struct AppConfig {
pub database_url: String,
pub wechat_appid: String,
pub wechat_secret: String,
pub jwt_secret: String,
pub ssl_key_path: String,
pub ssl_cert_path: String,
pub rust_log: String,
pub app_version: String,
pub environment: String,
pub free_user_data_limit: i32,
pub server_host: String,
pub server_port: u16,
}
impl AppConfig {
pub fn load() -> Result<Self, ConfigError> {
// 从环境变量读取当前环境,默认为 development
let env = std::env::var("APP_ENV").unwrap_or_else(|_| "development".into());
let config = Config::builder()
// 1. 先加载默认配置
.add_source(File::with_name("config/default"))
// 2. 再加载当前环境配置(覆盖默认值)
.add_source(File::with_name(&format!("config/{}", env)).required(false))
// 3. 最后从环境变量加载(最高优先级)
.add_source(config::Environment::with_prefix("APP"))
.build()?;
config.try_deserialize()
}
}
```
#### 方案二:简化方案(最小改动)
保持现有 `.env` 结构不变,通过 `APP_ENV` 环境变量和 `.env.development` / `.env.production` 文件区分:
**`.env.example`(提交到仓库的配置模板)**
```bash
# 必填配置
DATABASE_URL=postgres://user:pass@host:port/dbname
JWT_SECRET=your-secret-key
WECHAT_APPID=your-wechat-appid
WECHAT_SECRET=your-wechat-secret
# 可选配置(带默认值)
APP_ENV=development
RUST_LOG=info
APP_VERSION=0.2.3
FREE_USER_DATA_LIMIT=20
SSL_KEY_PATH=
SSL_CERT_PATH=
```
**部署脚本增强**
```bash
#!/bin/bash
# deploy.sh
# 接收环境参数
ENV=${1:-production}
# 根据环境加载不同配置
if [ "$ENV" = "development" ]; then
source .env.development
elif [ "$ENV" = "production" ]; then
source .env.production
fi
# 构建和部署...
```
### 环境切换操作指南
| 场景 | 操作方法 |
|------|----------|
| 本地开发 | `APP_ENV=development cargo run`,连接本地数据库 |
| 测试服务器部署 | `APP_ENV=development ./deploy.sh` |
| 生产环境部署 | `APP_ENV=production ./deploy.sh` 或默认 `./deploy.sh` |
| 查看当前环境 | 启动后访问 `/health` 接口或检查日志 |
### 实施步骤
**第一阶段(最小改动)**
1. 创建 `.env.example` 配置模板,移除敏感信息
2. 在 `deploy.sh` 中添加 `APP_ENV` 参数支持
3. 创建 `.env.development` 本地开发配置(可选加入 .gitignore
**第二阶段(推荐)**
1. 添加 `config` crate 依赖
2. 创建 `config/default.toml` 和 `config/production.toml`
3. 重构 `config.rs` 使用 config crate
4. 更新 `deploy.sh` 使用新的配置加载方式
### 相关改进项
- 本改进与"前后端版本统一管理"(改进路线图 P1可合并实施
- 本改进与"拆分 main.rs 路由处理器"(改进路线图 P1有协同效应
---
## 十一、检查清单
### 代码提交前检查
- [ ] 通过 `cargo clippy` 检查
- [ ] 通过 `cargo fmt` 格式化
- [ ] 单元测试通过
- [ ] 无硬编码的敏感信息
- [ ] 配置文件不包含实际密钥
### 部署前检查
- [ ] 数据库迁移脚本准备
- [ ] 环境变量配置检查
- [ ] 备份当前版本
- [ ] 健康检查接口正常
- [ ] 确认目标环境的配置正确
### 安全检查
- [ ] 输入验证完整
- [ ] 错误信息不暴露敏感数据
- [ ] 认证和授权正确
- [ ] 日志不记录敏感信息
- [ ] 生产环境使用强密钥
---
**最后更新**2026-04-14
**维护者**milky