优化: Keep-Alive/rate-limiter/dead-code清理 + deploy.sh蓝绿自动检测 + 压测文档
This commit is contained in:
167
docs/MAINTENANCE-MODE-RUNBOOK.md
Normal file
167
docs/MAINTENANCE-MODE-RUNBOOK.md
Normal file
@@ -0,0 +1,167 @@
|
||||
# 支付维护模式 Runbook
|
||||
|
||||
> 当支付宝支付失效时的应急操作手册。涵盖开启/关闭维护模式、切换到 Mock 支付、修复支付宝配置三种方案。
|
||||
|
||||
---
|
||||
|
||||
## 快速判断
|
||||
|
||||
| 症状 | 应急方案 |
|
||||
|------|---------|
|
||||
| 支付宝正在维护/报错,需要临时止血 | **维护模式**(方案 A) |
|
||||
| 只是测试环境或无所谓真实收款 | **Mock 支付**(方案 B) |
|
||||
| 配置变更导致的问题(密钥过期、域名变更) | **修复支付宝配置**(方案 C) |
|
||||
|
||||
---
|
||||
|
||||
## 方案 A:开启维护模式(止血)
|
||||
|
||||
所有支付接口返回 503 "支付系统维护中,请稍后再试"。
|
||||
|
||||
### 前置条件
|
||||
|
||||
SSH 免密码登录到 `root@1panel-server`。
|
||||
|
||||
```bash
|
||||
ssh root@1panel-server
|
||||
```
|
||||
|
||||
### ⚠️ 关键陷阱:生产服务器使用蓝绿部署
|
||||
|
||||
| Service | 端口 | 目录 | 是否承担生产流量 |
|
||||
|---------|------|------|----------------|
|
||||
| `rust-backend-green.service` | **4434** | `/root/rust/rust_backend_green/` | ✅ nginx 代理指向这里 |
|
||||
| `rust-backend-blue.service` | 4433 | `/root/rust/rust_backend_blue/` | ❌ 备用 |
|
||||
| `rust-backend.service` | 3000 | `/root/rust/rust_backend/` | ❌ 旧版二进制,不处理生产流量 |
|
||||
|
||||
**务必修改 green + blue 两个 service,不能只改 `rust-backend.service`**。
|
||||
|
||||
Nginx 配置位置:`/opt/1panel/apps/openresty/openresty/www/sites/xmclassmate.top/proxy/root.conf`
|
||||
|
||||
### 操作步骤
|
||||
|
||||
```bash
|
||||
# 1. 在 green(当前活跃)和 blue(备用)中都添加
|
||||
sed -i '/^\[Service\]/a Environment=PAYMENT_MAINTENANCE_MODE=true' /etc/systemd/system/rust-backend-green.service
|
||||
sed -i '/^\[Service\]/a Environment=PAYMENT_MAINTENANCE_MODE=true' /etc/systemd/system/rust-backend-blue.service
|
||||
|
||||
# 2. 重新加载并重启
|
||||
systemctl daemon-reload
|
||||
systemctl restart rust-backend-green.service
|
||||
systemctl restart rust-backend-blue.service
|
||||
|
||||
# 3. 验证
|
||||
curl -s -w "\nHTTP %{http_code}\n" https://xmclassmate.top/payment
|
||||
# 预期:HTTP 503 + HTML 中显示"支付系统维护中"
|
||||
```
|
||||
|
||||
### 恢复
|
||||
|
||||
```bash
|
||||
ssh root@1panel-server
|
||||
sed -i '/PAYMENT_MAINTENANCE_MODE/d' /etc/systemd/system/rust-backend-green.service
|
||||
sed -i '/PAYMENT_MAINTENANCE_MODE/d' /etc/systemd/system/rust-backend-blue.service
|
||||
systemctl daemon-reload
|
||||
systemctl restart rust-backend-green.service
|
||||
systemctl restart rust-backend-blue.service
|
||||
|
||||
# 验证
|
||||
curl -s -w "\nHTTP %{http_code}\n" https://xmclassmate.top/payment
|
||||
# 预期:HTTP 200 + 套餐选择页 HTML
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 方案 B:切换到 Mock 支付(快速恢复可用)
|
||||
|
||||
### 原理
|
||||
|
||||
当代码检测到 `ALIPAY_*` 环境变量不存在时,自动启用 Mock 支付(无需配置 `MOCK_PAY_ENABLED=true`)。
|
||||
|
||||
### 操作步骤
|
||||
|
||||
```bash
|
||||
ssh root@1panel-server
|
||||
|
||||
# 1. 编辑 green service,注释掉支付宝配置
|
||||
systemctl edit rust-backend-green.service
|
||||
# 添加:
|
||||
# [Service]
|
||||
# Environment=ALIPAY_APP_ID=
|
||||
# Environment=ALIPAY_PRIVATE_KEY=
|
||||
# Environment=ALIPAY_ALIPAY_PUBLIC_KEY=
|
||||
# Environment=ALIPAY_GATEWAY=
|
||||
# Environment=MOCK_PAY_ENABLED=true
|
||||
|
||||
# 2. 同样操作 blue service
|
||||
systemctl edit rust-backend-blue.service
|
||||
|
||||
# 3. 重启
|
||||
systemctl daemon-reload
|
||||
systemctl restart rust-backend-green.service
|
||||
systemctl restart rust-backend-blue.service
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 方案 C:修复支付宝配置
|
||||
|
||||
### 检查清单
|
||||
|
||||
1. 登录 [支付宝开放平台](https://open.alipay.com) 检查应用状态
|
||||
2. 确认 RSA2 密钥对是否匹配(私钥与公钥配对)
|
||||
3. 确认异步通知 URL(notify_url)在应用白名单中
|
||||
4. 确认网关地址正确:
|
||||
- 沙箱:`https://openapi-sandbox.dl.alipaydev.com/gateway.do`
|
||||
- 正式:`https://openapi.alipay.com/gateway.do`
|
||||
5. 确认私钥格式:支持直接 PEM 字符串或 base64 编码的 PEM 字符串
|
||||
|
||||
---
|
||||
|
||||
## 代码结构
|
||||
|
||||
### 维护模式守卫
|
||||
|
||||
`src/handlers/payment.rs`:
|
||||
|
||||
```rust
|
||||
fn check_payment_maintenance() -> Result<(), AppError> {
|
||||
if std::env::var("PAYMENT_MAINTENANCE_MODE").ok() == Some("true".to_string()) {
|
||||
return Err(AppError::ServiceUnavailable("支付系统维护中,请稍后再试".to_string()));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
```
|
||||
|
||||
### Mock 支付守卫
|
||||
|
||||
```rust
|
||||
fn check_mock_payment_allowed(req: &HttpRequest) -> Result<(), AppError> {
|
||||
// 规则 1:有支付宝配置时永不走 Mock
|
||||
if AlipayConfig::from_env().is_some() {
|
||||
return Err(AppError::BadRequest("真实支付已启用,Mock 支付不可用".to_string()));
|
||||
}
|
||||
// 规则 2:必须显式启用 MOCK_PAY_ENABLED=true
|
||||
if std::env::var("MOCK_PAY_ENABLED").ok() != Some("true".to_string()) {
|
||||
return Err(AppError::Forbidden("Mock 支付未启用".to_string()));
|
||||
}
|
||||
// 规则 3(可选):如果设了 MOCK_PAY_KEY,验证请求头 X-Mock-Key
|
||||
Ok(())
|
||||
}
|
||||
```
|
||||
|
||||
### 错误页面渲染
|
||||
|
||||
`src/error.rs` 中的 `ResponseError` 实现:`ServiceUnavailable` 返回 503 HTML 错误页。
|
||||
|
||||
---
|
||||
|
||||
## 相关文件
|
||||
|
||||
| 文件 | 说明 |
|
||||
|------|------|
|
||||
| `/etc/systemd/system/rust-backend-green.service` | 生产活跃服务(4434) |
|
||||
| `/etc/systemd/system/rust-backend-blue.service` | 生产备用服务(4433) |
|
||||
| `/etc/systemd/system/rust-backend.service` | 旧版服务(3000,不处理生产流量) |
|
||||
| `src/handlers/payment.rs` | 支付处理器 + 维护模式守卫 |
|
||||
| `src/error.rs` | 错误处理 + 503 页面渲染 |
|
||||
Reference in New Issue
Block a user