docs(backend): 完善 IMPROVEMENTS.md - 添加环境区分机制解决方案
This commit is contained in:
210
IMPROVEMENTS.md
210
IMPROVEMENTS.md
@@ -304,27 +304,231 @@
|
||||
- 影响:开发效率
|
||||
- 工作量:中等
|
||||
|
||||
## 九、检查清单
|
||||
## 十、缺少环境区分机制
|
||||
|
||||
### 问题描述
|
||||
|
||||
当前后端项目未区分生产环境和开发/测试环境,所有配置混在一个 `.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-13
|
||||
**维护者**:开发团队
|
||||
**最后更新**:2026-04-14
|
||||
**维护者**:milky
|
||||
|
||||
Reference in New Issue
Block a user