Files
danyang-match/部署架构、运维监控、备份恢复与升级方案.md
WorkBuddy 4f37df3284 docs: 废止被取代的 Phase-13A 首轮报告与 V1.0 部署方案(原地重写,不用 git rm)
- docs/Phase-13A-V11-Completion-Report.md:2026-09-08 首轮报告自报「✅ 核心链路已完成」,
  已被 Phase-13A-V11-Recovery-Completion-Report-2026-09-17.md(CLOSED,Gate 全项通过)取代。
  该文件因命名差异(`Phase-13A-` 带 13A、缺数字段)不匹配清理清单的 `Phase-XX-` 模式而漏删。
  **原地重写为废止声明**而非 git rm —— 本机 safe-delete 钩子会把「删文件」放大为「删父目录」
  (2026-09-18 实测:一次 git rm 导致整个 docs/ 被移除,已从 Git 完整恢复)。

- 部署架构、运维监控、备份恢复与升级方案.md:补 V1.1 取代头注(方案任务二点名要求,此前遗漏)。

另登记一份**不删**的:docs/Phase-V11-Deployment-Completion-Report.md(2026-09-09,含已被推翻的
「16/16 E2E 通过」)—— 它不在方案删除目标模式内,且被保留文档
Phase-01-V11-Recovery-Completion-Report-2026-09-09.md 援引,删除会制造悬空引用,保留待决。
2026-09-18 21:15:13 +08:00

4417 lines
52 KiB
Markdown
Raw Permalink 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.
# 丹阳公益婚恋服务平台
# V1.0 部署架构、运维监控、备份恢复与升级方案
> **⚠️ 已被取代(2026-09-18 头注)**:本文件为 V1.0 部署运维方案。V1.1 的部署与运维口径以
> `docs/OPS.md`(运维手册)、`infrastructure/`(compose / nginx / scripts,其中 `docker-compose.prod.yml`
> 刻意不进版本控制)与 `docs/善缘丹阳 V1.1 客户需求基线增量开发与修复计划.md` 的 **Phase 22(Deployment / Ops)**
> 为准。本文件保留原位,仅作为 V1.0 部署架构与历史决策的出处 —— 其中的**端口、主机名、目录结构可能已与现网不符**,
> 不得作为实施依据。
>
> 交接说明:`AGENTS.md` 的「文档」节未收录本文件;`docs/Phase-01-V11-Recovery-Completion-Report-2026-09-09.md`
> 仍援引它作为 Phase 01 的核对对象(属历史记录,保留)。
版本:V1.0
适用范围:微信小程序后端、公益红娘工作台、运营管理后台、PostgreSQL、Redis、对象存储、WebSocket、日志与监控系统
核心目标:低成本、易部署、易维护、可备份、可恢复、可升级、故障可定位、后期可平滑扩容
---
# 第一章 部署设计目标
V1.0部署方案不追求复杂云原生架构。
当前项目更需要:
> **少组件、低运维成本、可靠、容易备份、出现问题容易排查。**
因此V1优先:
```text
Docker
+
Docker Compose
+
Nginx
+
后端应用
+
PostgreSQL
+
Redis
+
对象存储
```
暂不引入:
- Kubernetes
- Service Mesh
- Kafka
- Elasticsearch
- 分布式数据库
- 多地域复杂集群
- 大型日志平台
- 大型微服务体系
---
# 第二章 V1总体部署架构
推荐:
```text
微信小程序
│
│ HTTPS / WSS
↓
┌───────────┐
│ Nginx │
└─────┬─────┘
│
┌───────────┴───────────┐
│ │
↓ ↓
Backend API Admin Web
+ WebSocket 静态资源
│
┌──────┼───────────────┐
│ │ │
↓ ↓ ↓
PostgreSQL Redis Object Storage
│
↓
Backup System
```
---
# 第三章 部署形态建议
V1优先采用:
> **单区域部署。**
如果选择云服务器:
建议中国大陆节点。
核心业务数据:
> 优先存储于中国大陆。
这样更适合:
- 微信小程序访问
- 国内网络
- 用户隐私
- 后续合规管理
---
# 第四章 初期服务器数量
V1早期推荐:
> 1台应用服务器 + 独立数据库/托管数据库。
或者低预算情况下:
> 1台应用服务器 + 1台数据库服务器。
不建议:
> 所有应用、数据库、备份全放同一个Docker宿主机。
因为宿主机故障后:
> 全平台一起失效。
---
# 第五章 推荐初期架构A
低维护优先:
```text
云服务器A
├── Nginx
├── Backend
├── Admin Web
└── Redis
云数据库
└── PostgreSQL
对象存储
└── 用户照片/聊天图片/活动图片
```
优点:
- PostgreSQL少维护
- 云数据库自动备份较方便
- 应用服务器故障不影响数据库持久数据
---
# 第六章 推荐初期架构B
成本优先:
```text
服务器A
├── Nginx
├── Backend
├── Admin Web
└── Redis
服务器B
└── PostgreSQL
```
对象存储:
> 云对象存储。
适合:
> 希望降低托管数据库费用,但有一定服务器维护能力。
---
# 第七章 不推荐架构
不建议:
```text
一台服务器
├── Backend
├── PostgreSQL
├── Redis
├── 用户图片目录
├── Backup
└── 所有日志
```
因为:
> 一块磁盘坏掉可能同时丢生产和备份。
---
# 第八章 Docker部署原则
所有核心应用统一:
> Docker化。
包括:
```text
backend
nginx
redis(如果自建)
admin-web
```
PostgreSQL是否Docker:
- 开发/Test可以
- 生产更推荐托管数据库或独立服务器
---
# 第九章 Docker镜像原则
镜像必须:
- 可重复构建
- 固定版本
- 不使用latest生产部署
- 保留版本历史
例如:
```text
matchmaking-backend:1.0.0
matchmaking-backend:1.0.1
```
禁止:
```text
matchmaking-backend:latest
```
作为唯一可追溯版本。
---
# 第十章 Docker Compose
V1生产仍可以使用:
```text
docker compose
```
无需Kubernetes。
示例逻辑:
```yaml
services:
nginx:
backend:
redis:
admin-web:
```
数据库如果外部托管:
> 不放Compose。
---
# 第十一章 推荐项目部署目录
服务器建议:
```text
/opt/matchmaking/
├── compose/
├── env/
├── nginx/
├── scripts/
├── logs/
├── backups/
└── releases/
```
---
# 第十二章 Releases目录
例如:
```text
releases/
├── 1.0.0/
├── 1.0.1/
└── 1.1.0/
```
保留近期稳定版本。
---
# 第十三章 环境划分
正式至少:
```text
dev
test
staging
prod
```
---
# 第十四章 Dev环境
用途:
> 开发。
允许:
- Docker本地数据库
- 模拟实名认证
- 模拟短信
- 测试对象存储
---
# 第十五章 Test环境
用于:
- CI
- API测试
- 并发测试
- 自动化测试
数据:
> 可随时重置。
---
# 第十六章 Staging
必须尽量接近Prod。
包括:
- HTTPS
- Nginx
- Redis
- PostgreSQL同主版本
- 对象存储权限策略
- WebSocket
- Migration流程
---
# 第十七章 Production
严格:
> 禁止使用测试Secret。
禁止:
> Debug模式。
禁止:
> 暴露数据库公网端口。
---
# 第十八章 配置管理
配置分为:
```text
业务配置
部署配置
Secret
```
---
# 第十九章 业务配置
例如:
```text
dailyRecommendationLimit
maxProfilePhotos
activityEnabled
matchmakerEnabled
```
由:
> system_configs
管理。
---
# 第二十章 部署配置
例如:
```text
PORT
DATABASE_HOST
REDIS_HOST
OBJECT_STORAGE_ENDPOINT
LOG_LEVEL
```
通过环境变量。
---
# 第二十一章 Secret
例如:
```text
DATABASE_PASSWORD
JWT_SECRET
WECHAT_SECRET
REAL_NAME_PROVIDER_SECRET
OBJECT_STORAGE_SECRET
```
禁止写入:
- Git
- Dockerfile
- 前端代码
- README示例真实值
---
# 第二十二章 .env管理
开发:
```text
.env.example
```
只提供键名。
生产:
> 实际.env不提交Git。
权限:
```text
chmod 600
```
或使用云Secret服务。
---
# 第二十三章 Nginx职责
Nginx负责:
```text
HTTPS
反向代理
静态后台资源
WebSocket代理
基础安全Header
请求体大小限制
访问日志
```
---
# 第二十四章 域名结构建议
例如:
```text
api.example.com
admin.example.com
```
小程序:
```text
api.example.com
```
后台:
```text
admin.example.com
```
---
# 第二十五章 API路径
```text
https://api.example.com/api/v1/
```
WebSocket:
```text
wss://api.example.com/ws
```
---
# 第二十六章 HTTPS
生产必须:
> TLS。
HTTP:
> 自动301跳HTTPS。
---
# 第二十七章 TLS证书
建议:
- 自动续期
- 到期监控
避免:
> 证书过期导致微信小程序整体不可访问。
---
# 第二十八章 Nginx上传大小
根据业务配置。
例如:
```text
client_max_body_size 12M
```
与图片上传限制一致。
---
# 第二十九章 WebSocket代理
必须配置:
```text
Upgrade
Connection
```
确保长期连接正常。
---
# 第三十章 API超时
普通API:
> 不宜设置过长。
例如:
```text
proxy_read_timeout 30s
```
推荐服务也应在合理时间内返回。
不能靠:
> 5分钟HTTP超时
掩盖慢SQL。
---
# 第三十一章 WebSocket超时
WebSocket需要单独配置更长连接策略。
配合:
> 应用心跳。
---
# 第三十二章 后端实例
V1初期:
```text
backend x1
```
足够。
架构必须保证后续:
```text
backend x2
```
容易扩展。
---
# 第三十三章 无状态设计
Backend尽量无状态。
Session:
> Redis/数据库。
用户图片:
> Object Storage。
不能存在:
```text
/app/uploads/user1.jpg
```
作为正式生产唯一文件。
否则多实例后无法共享。
---
# 第三十四章 后端扩容
当单实例不足:
```text
Nginx
├── backend-1
└── backend-2
```
即可。
---
# 第三十五章 多实例WebSocket
未来:
```text
backend-1
backend-2
```
需要:
> Redis Pub/Sub或等效机制
进行跨实例实时推送。
V1单实例时可以简化。
---
# 第三十六章 PostgreSQL定位
PostgreSQL是:
> 核心业务事实数据源。
保存:
- 用户
- 认证状态
- 资料
- Match
- Conversation
- Message
- Activity
- Matchmaker
- Risk
- Audit
---
# 第三十七章 PostgreSQL生产原则
必须:
- 独立账号
- 强密码
- 禁止公网开放
- 定期备份
- 监控连接数
- 监控磁盘
- 执行Migration管理
---
# 第三十八章 数据库账号建议
至少:
```text
app_user
migration_user
backup_user
```
---
# 第三十九章 app_user
仅拥有:
> 应用需要的CRUD。
不要:
> SUPERUSER。
---
# 第四十章 migration_user
用于:
> 数据库结构升级。
权限较高。
正常应用不使用。
---
# 第四十一章 backup_user
只拥有:
> 必要读取/备份权限。
---
# 第四十二章 数据库连接池
必须限制:
> 最大连接数。
不能每个API请求开新连接。
连接池大小根据服务器配置和数据库容量设置。
不要盲目设:
```text
500
```
---
# 第四十三章 慢SQL监控
建议记录:
> 超过指定时间的SQL。
例如:
```text
> 500ms
```
作为初始告警参考。
具体阈值可调整。
---
# 第四十四章 数据库关键监控
至少:
```text
CPU
Memory
Disk
Connections
Slow Queries
Locks
Replication(若未来启用)
Backup Status
```
---
# 第四十五章 数据库磁盘告警
建议:
```text
70% warning
85% critical
```
数值可根据环境调整。
关键是:
> 提前告警。
---
# 第四十六章 Redis定位
Redis只做:
- Cache
- Session
- Rate Limit
- WebSocket在线状态
- 临时未读优化
- 分布式锁/短锁(必要)
Redis不是核心事实数据源。
---
# 第四十七章 Redis丢失原则
即使Redis全部清空:
> 平台核心业务数据不能永久丢失。
最多:
- 缓存重建
- 用户重新登录
- 推荐重新计算
- 未读重新统计
---
# 第四十八章 Redis生产安全
必须:
- 非公网
- 密码/ACL
- 网络隔离
- 最大内存
- 淘汰策略
---
# 第四十九章 Redis持久化
如果Redis用于:
> 重要Session
可以开启合理持久化。
但仍不能把:
> Match/Message
只放Redis。
---
# 第五十章 对象存储
存:
```text
用户头像
生活照片
聊天图片
活动图片
举报证据
```
---
# 第五十一章 Bucket划分建议
可以:
```text
profile-private
chat-private
activity-assets
risk-evidence-private
```
或者一个Private Bucket按Prefix隔离。
---
# 第五十二章 对象存储默认Private
必须:
```text
Public Access = Off
```
---
# 第五十三章 用户访问图片
流程:
```text
客户端请求
↓
业务权限校验
↓
Backend生成短时Signed URL
↓
客户端访问对象存储
```
---
# 第五十四章 Signed URL
有效时间:
> 短时。
例如数分钟。
具体按使用体验配置。
---
# 第五十五章 风控证据Bucket
建议更加严格:
- 更短Signed URL
- 专门权限
- 访问审计
---
# 第五十六章 对象存储生命周期
临时上传:
```text
tmp/
```
未绑定业务:
> 自动清理。
---
# 第五十七章 图片正式文件
按业务类型分类Prefix:
```text
profiles/{userId}/
chat/{conversationId}/
activities/{activityId}/
reports/{reportId}/
```
---
# 第五十八章 日志体系
V1至少分:
```text
application.log
access.log
security.log
audit(数据库)
```
---
# 第五十九章 Application Log
记录:
- Service异常
- 第三方错误
- 系统异常
- 任务执行结果
---
# 第六十章 Access Log
Nginx/API:
```text
requestId
method
path
status
latency
clientIp
userAgent
```
---
# 第六十一章 Security Log
例如:
```text
后台登录失败
大量Rate Limit
异常Token
权限越权
可疑上传
```
---
# 第六十二章 Audit
正式业务审计:
> 存数据库。
不能只存在日志文件。
---
# 第六十三章 日志统一RequestId
从Nginx开始:
```text
RequestId
```
贯穿:
```text
Nginx
→ Backend
→ Service
→ Error Log
```
方便故障排查。
---
# 第六十四章 日志格式
推荐结构化JSON。
例如:
```json
{
"level": "ERROR",
"requestId": "req_xxx",
"service": "match",
"code": "MATCH_CREATE_FAILED"
}
```
---
# 第六十五章 禁止日志内容
严禁:
```text
身份证全文
完整手机号
AccessToken
RefreshToken
密码
聊天正文
举报完整证据
对象存储Secret
```
---
# 第六十六章 日志保留
具体期限:
> 根据数据安全政策确定。
建议:
- 普通应用日志短期
- Security Log较长期
- Audit按照审计要求长期管理
不要无差别永久保存所有日志。
---
# 第六十七章 日志轮转
必须:
> Log Rotation。
防止日志占满磁盘。
例如:
- 按天
- 按大小
- 保留指定天数
- 自动压缩
---
# 第六十八章 监控总体结构
V1建议:
```text
基础设施监控
+
应用监控
+
业务监控
+
安全监控
```
---
# 第六十九章 基础设施监控
监控:
```text
CPU
Memory
Disk
Network
Container
PostgreSQL
Redis
```
---
# 第七十章 应用监控
监控:
```text
QPS
P95
5xx
4xx
线程/事件循环状态
DB连接池
外部API
WebSocket
```
---
# 第七十一章 业务监控
重点:
```text
登录成功率
实名认证失败率
待审核数量
推荐失败
Match创建异常
Message失败
Activity报名失败
Report积压
```
---
# 第七十二章 安全监控
重点:
```text
后台连续登录失败
大量401/403
Rate Limit异常
敏感数据访问
高风险操作
权限修改
```
---
# 第七十三章 监控工具原则
V1不要求昂贵商业APM。
可采用:
> Prometheus + Grafana
或云厂商原生监控。
如果采用云平台:
优先选择:
> 少维护方案。
---
# 第七十四章 是否必须自建Prometheus
不是。
如果云厂商:
- 主机监控
- 数据库监控
- 日志告警
已经足够:
> V1可先使用云监控。
目标是:
> 能发现问题。
不是为了建设监控平台。
---
# 第七十五章 最低必须监控项
上线前必须有:
```text
服务器CPU
服务器内存
服务器磁盘
Backend存活
HTTP 5xx
PostgreSQL
Redis
数据库备份结果
HTTPS证书到期
```
---
# 第七十六章 Health Check
建议:
```text
/health/live
/health/ready
```
---
# 第七十七章 Live
判断:
> 应用进程是否活着。
不能把所有第三方都放Live。
否则第三方短信挂了:
> 容器被不断重启。
---
# 第七十八章 Ready
判断:
> 是否能正常提供核心服务。
可以检查:
- PostgreSQL
- 必要Redis连接
---
# 第七十九章 第三方健康
实名认证、微信等:
> 单独监控。
不要作为应用存活唯一依据。
---
# 第八十章 告警渠道
至少:
- 手机
- 企业微信/微信工作群
- 邮件(可选)
关键事故:
> 不能只发到没人看的监控页面。
---
# 第八十一章 告警分级
建议:
```text
P1 紧急
P2 重要
P3 提醒
```
---
# 第八十二章 P1告警
例如:
```text
生产API整体不可用
PostgreSQL不可用
磁盘接近满
大量500
权限绕过事件
备份连续失败
```
---
# 第八十三章 P2告警
例如:
```text
推荐失败率异常
WebSocket连接失败率高
实名认证错误率高
活动报名异常
```
---
# 第八十四章 P3
例如:
- 某异步任务一次失败
- 日志增量异常
- 非核心第三方短暂失败
---
# 第八十五章 告警防噪音
不要:
> CPU瞬间80%就每分钟报警。
使用:
- 持续时间
- 连续次数
- 恢复通知
避免告警疲劳。
---
# 第八十六章 生产Dashboard
运维Dashboard重点:
```text
API availability
P95 latency
Error Rate
DB Health
Redis Health
Disk
WebSocket connections
External service status
```
---
# 第八十七章 备份总体原则
必须保证:
> **生产数据损坏后可以恢复。**
不是:
> “我们每天有一个backup.zip”。
真正要求:
```text
有备份
+
备份可读取
+
备份异地
+
实际恢复验证
```
---
# 第八十八章 数据库备份
建议:
```text
每日全量备份
+
数据库服务自身时间点恢复能力(如果使用托管数据库)
```
---
# 第八十九章 自建PostgreSQL
至少:
> 每日逻辑/物理备份。
更可靠方案:
> WAL归档 + 全量备份。
V1具体方案根据部署预算决定。
---
# 第九十章 托管数据库
优先利用:
- 自动备份
- 时间点恢复
- 跨可用区备份(如适用)
但仍需:
> 验证恢复操作。
---
# 第九十一章 备份保留策略建议
例如:
```text
每日备份:7~14份
每周备份:4~8份
每月备份:若干
```
具体期限结合:
- 成本
- 合规
- 风险
最终确定。
不是业务硬编码。
---
# 第九十二章 备份不要只在原机器
错误:
```text
PostgreSQL
和
backup.sql
都在同一磁盘
```
宿主机坏了:
> 两个一起没。
---
# 第九十三章 异地/异介质备份
至少:
> 备份复制到不同存储位置。
例如:
```text
云数据库
+
对象存储Backup Bucket
```
---
# 第九十四章 备份加密
备份中可能含:
> 高敏感数据。
因此:
- 存储加密
- 访问控制
- 密钥保护
---
# 第九十五章 Backup Bucket
必须:
> Private。
只有备份角色可访问。
---
# 第九十六章 备份账号
不使用:
> super admin通用云账号。
使用:
> 独立Backup权限。
---
# 第九十七章 Redis备份
Redis数据可重建。
因此Redis备份优先级低于PostgreSQL。
若存Session等:
> 可保留合理快照。
但恢复生产最核心的是:
> PostgreSQL。
---
# 第九十八章 对象存储备份
用户图片本身也是重要数据。
建议:
- Bucket版本控制(如果成本允许)
- 生命周期
- 跨存储备份/冗余
至少确保:
> 数据库恢复后不会出现所有图片都找不到。
---
# 第九十九章 对象删除策略
业务删除:
> 先soft delete/状态标记。
对象存储真正物理删除:
> 经过延迟清理任务。
避免用户误操作后立刻不可恢复。
---
# 第一百章 删除延迟
例如:
> 7~30天后物理清理。
具体根据数据保留政策确定。
安全举报证据等:
> 按独立保留策略处理。
---
# 第一百零一章 数据库恢复目标
建议定义:
```text
RPO
RTO
```
---
# 第一百零二章 RPO
Recovery Point Objective:
> 最多能接受丢多久的数据。
V1建议目标:
> 尽量控制在小时级或更好。
若使用托管数据库PITR:
> 可显著降低RPO。
---
# 第一百零三章 RTO
Recovery Time Objective:
> 故障后多久恢复服务。
V1建议:
> 数小时内恢复核心服务。
不追求金融级秒级容灾。
---
# 第一百零四章 RPO/RTO属于建议目标
最终根据:
- 云服务
- 预算
- 活跃用户规模
正式确定。
不要写入代码。
---
# 第一百零五章 恢复演练
至少:
> 每季度/半年实际恢复一次测试数据库。
早期可以:
> 每次大版本上线前至少一次。
---
# 第一百零六章 恢复测试流程
```text
下载备份
↓
新建隔离数据库
↓
Restore
↓
运行Migration校验
↓
执行数据一致性检查
↓
抽查用户/Match/Message/Activity
↓
记录结果
```
---
# 第一百零七章 恢复检查
至少:
```text
users count
matches count
messages count
activities count
reports count
audit logs
```
并检查外键关系。
---
# 第一百零八章 恢复演练记录
记录:
```text
backupTime
restoreTime
duration
result
errors
operator
```
---
# 第一百零九章 配置备份
不仅数据库。
还需要备份:
```text
Nginx配置
Docker Compose
Migration脚本
系统公开配置
监控规则
部署脚本
```
这些本身应在:
> Git版本管理。
---
# 第一百一十章 Secret备份
Secret不能丢。
但不能放普通Git。
应使用:
- Secret Manager
- 加密离线备份
---
# 第一百一十一章 灾难恢复优先顺序
```text
1 PostgreSQL
2 Backend
3 Auth
4 核心用户/Match
5 Chat
6 Object Storage
7 Redis Cache
8 Analytics
```
核心服务优先。
统计可以最后恢复。
---
# 第一百一十二章 Redis全部丢失恢复
流程:
```text
启动新Redis
↓
Session可能失效
↓
用户重新登录
↓
缓存自然重建
```
核心Match不会丢。
---
# 第一百一十三章 应用服务器损坏
如果镜像和配置都在版本库/镜像仓库:
```text
新服务器
↓
Docker
↓
部署Compose
↓
配置Secret
↓
启动
↓
Nginx/域名切换
```
即可。
---
# 第一百一十四章 应用服务器不能成为“手工艺术品”
禁止:
> 开发人员SSH进去改了一堆东西但没有记录。
所有正式变更:
> 进入部署脚本、Compose或配置仓库。
---
# 第一百一十五章 Infrastructure Documentation
至少记录:
```text
服务器
域名
证书
数据库
Redis
对象存储
备份位置
监控入口
关键联系人
```
但Secret单独管理。
---
# 第一百一十六章 Release流程
建议:
```text
开发完成
↓
CI
↓
Test
↓
Build Image
↓
Staging
↓
Migration
↓
E2E
↓
RC
↓
Production
↓
Smoke
↓
监控
```
---
# 第一百一十七章 Production发布不在服务器编译
禁止:
```text
git pull
npm install
mvn package
```
直接生产机器现场编译。
应该:
```text
CI构建
↓
生成镜像
↓
生产只拉镜像
```
---
# 第一百一十八章 镜像仓库
使用:
> 国内访问稳定的Container Registry。
保存:
```text
1.0.0
1.0.1
```
---
# 第一百一十九章 CI输出
每次Release至少生成:
```text
backend image
admin build
migration package
release notes
```
---
# 第一百二十章 Version
后端提供:
```text
/version
```
或健康接口返回:
```json
{
"version": "1.0.0",
"commit": "abc123"
}
```
方便确认当前服务器版本。
---
# 第一百二十一章 数据库Migration
必须使用:
> 正式Migration工具。
例如具体框架对应:
- Flyway
- Liquibase
- Prisma Migration
- TypeORM migration
根据最终技术栈选择。
禁止:
> 生产手工改表后不记录。
---
# 第一百二十二章 Migration版本
例如:
```text
V001__initial_schema
V002__activity_interest
V003__add_match_rule_version
```
---
# 第一百二十三章 Migration原则
必须:
- 可重复部署环境
- 可审核
- Staging先跑
- 生产前备份
- 记录执行结果
---
# 第一百二十四章 大表Migration
未来数据量大时:
避免:
> 一次长时间锁表。
V1早期数据量小问题有限。
但仍建立正确习惯。
---
# 第一百二十五章 向后兼容Migration
推荐:
### 第一步
增加字段。
### 第二步
新旧代码兼容。
### 第三步
数据迁移。
### 第四步
后续版本再清旧字段。
---
# 第一百二十六章 不建议Release中直接DROP重要字段
因为回滚应用后:
> 旧版本可能无法运行。
---
# 第一百二十七章 发布策略V1
推荐:
> Rolling/短停机发布。
单实例情况下:
可以短暂:
> 维护模式。
---
# 第一百二十八章 单实例发布
流程:
```text
开启维护模式(需要时)
↓
备份
↓
Migration
↓
启动新版本
↓
健康检查
↓
Smoke Test
↓
关闭维护模式
```
---
# 第一百二十九章 是否必须零停机
V1:
> 不必须。
宁愿:
> 几分钟明确维护窗口
也不要为了“零停机”引入复杂双活系统。
---
# 第一百三十章 维护页
用户看到:
> 系统正在进行短暂维护,请稍后再试。
不要:
> 502 Bad Gateway。
---
# 第一百三十一章 后台维护
管理员提前知道:
> 维护时间。
避免活动现场突然升级。
---
# 第一百三十二章 发布避开关键活动
正式部署不要安排在:
- 大型公益相亲活动签到前
- 活动进行中
- 大规模推广刚开始
优先低峰期。
---
# 第一百三十三章 灰度发布
如果未来多实例:
```text
backend-1 old
backend-2 new
```
可先少量流量到new。
V1初期不强制。
---
# 第一百三十四章 Feature Flag灰度
当前更实用:
```text
activityEnabled
imageChatEnabled
matchmakerEnabled
```
可以单独开关。
---
# 第一百三十五章 新功能上线方式
例如图片聊天:
```text
代码已部署
↓
Flag=false
↓
内部测试
↓
Flag=true
```
降低风险。
---
# 第一百三十六章 数据结构和Feature Flag
注意:
> 数据库Migration必须先完成。
不能Flag一开:
> 表还不存在。
---
# 第一百三十七章 Rollback原则
如果上线后出现严重问题:
> 应能快速回到上一稳定应用版本。
---
# 第一百三十八章 Rollback前提
数据库Migration必须考虑:
> 旧版本是否仍兼容。
---
# 第一百三十九章 应用回滚
例如:
```text
1.0.1有Bug
↓
切回1.0.0 image
↓
Restart
```
---
# 第一百四十章 数据库回滚
不建议:
> 自动Down Migration生产数据库。
更安全:
- 应用向后兼容
- 必要时修复Forward Migration
除非明确验证。
---
# 第一百四十一章 为什么数据库回滚更危险
生产已产生新数据。
简单:
```text
DROP COLUMN
```
可能直接丢数据。
因此:
> 应用回滚简单,数据库回滚谨慎。
---
# 第一百四十二章 Hotfix流程
严重线上Bug:
```text
建立hotfix branch
↓
最小修复
↓
自动测试
↓
Staging验证
↓
生成1.0.1
↓
上线
```
不能:
> SSH服务器现场改代码。
---
# 第一百四十三章 Release Notes
每个版本:
```text
新增
修复
数据库变更
配置变更
已知问题
回滚注意事项
```
---
# 第一百四十四章 运维日常SOP
每天:
```text
检查P1告警
检查备份
检查磁盘
查看严重错误
```
---
# 第一百四十五章 每周
```text
检查错误趋势
检查慢SQL
检查Redis
检查高风险安全日志
检查后台异常登录
```
---
# 第一百四十六章 每月
```text
检查资源容量
检查证书
检查数据库增长
检查对象存储增长
检查备份容量
检查权限和离职账号
```
---
# 第一百四十七章 每季度
```text
恢复演练
权限复核
安全补丁
依赖升级评估
灾备检查
```
---
# 第一百四十八章 容量监控
必须关注:
```text
用户数
照片量
消息量
数据库大小
对象存储大小
Redis内存
日志大小
```
---
# 第一百四十九章 容量增长预警
例如数据库:
> 预计30天后超过磁盘80%。
应该:
> 提前扩容。
不是等磁盘100%再处理。
---
# 第一百五十章 对象存储成本
聊天图片和生活照片可能成为主要存储增长。
建议统计:
```text
daily upload volume
total storage
```
---
# 第一百五十一章 图片压缩
正式上传后:
> 后端/图片服务压缩。
减少:
- 网络
- 存储
- CDN成本
---
# 第一百五十二章 是否需要CDN
V1用户集中丹阳/江苏。
如果对象存储已有加速能力:
> 可直接使用。
用户量上升后:
> 再评估CDN。
---
# 第一百五十三章 用户头像缓存
Signed URL虽然短时:
前端仍可:
> 本地短期缓存。
减少重复下载。
---
# 第一百五十四章 CDN不能破坏隐私
如果使用CDN:
> 私有内容仍需要鉴权/签名。
不能因为加CDN:
> 变成Public Bucket。
---
# 第一百五十五章 数据库扩容时机
出现:
- CPU长期高
- Connection接近上限
- 慢SQL明显
- 磁盘压力
先优化:
> SQL和索引。
再升级:
> 数据库规格。
---
# 第一百五十六章 不要一有性能问题就分库
V1单PostgreSQL足够。
优先:
```text
索引
查询优化
缓存
分页
资源升级
```
---
# 第一百五十七章 Redis扩容
主要根据:
> 内存。
缓存应设置TTL。
避免:
> 永不失效无限增长。
---
# 第一百五十八章 WebSocket容量
监控:
```text
在线连接
连接创建率
断线率
消息推送失败
```
达到单实例瓶颈后:
> 横向扩Backend。
---
# 第一百五十九章 推荐任务容量
如果实时推荐开始变慢:
第一阶段:
> Redis缓存。
第二阶段:
> 预计算。
仍无需立即引入推荐大数据平台。
---
# 第一百六十章 Analytics容量
统计变慢:
先使用:
> Daily Summary。
不要让Dashboard每次扫描messages全表。
---
# 第一百六十一章 Maintenance Jobs
建议至少:
```text
通知重试
临时文件清理
活动状态更新
推荐缓存清理
审核超时提醒
红娘超时提醒
统计日汇总
风险状态重算
```
---
# 第一百六十二章 Job执行机制
V1可以:
> 后端内置Scheduler。
不需要单独任务平台。
---
# 第一百六十三章 Scheduler多实例问题
未来Backend多实例:
必须避免:
> 同一个任务两台都跑。
可采用:
- Redis Lock
- DB Lock
- Scheduler Leader
---
# 第一百六十四章 Job必须幂等
例如Daily Analytics:
执行两次:
> 结果相同。
---
# 第一百六十五章 Job监控
记录:
```text
jobName
startedAt
finishedAt
status
error
```
重要任务失败:
> 告警。
---
# 第一百六十六章 临时文件清理Job
清理:
- 未绑定上传
- 过期临时文件
不能误删:
> 正式Profile/Chat/Risk文件。
---
# 第一百六十七章 Notification Retry
失败:
> 重试有限次数。
不能:
> 无限重试造成任务堆积。
---
# 第一百六十八章 第三方服务监控
至少:
```text
微信登录
实名认证
对象存储
短信(如启用)
```
---
# 第一百六十九章 第三方错误隔离
实名认证失败:
> 不应影响用户查看帮助页。
对象存储失败:
> 不应导致整个API死亡。
---
# 第一百七十章 Circuit Breaker
V1不一定需要引入复杂框架。
但第三方调用应:
- 超时
- 有限重试
- 快速失败
不能一个实名认证API卡30秒拖死线程池。
---
# 第一百七十一章 Third-party Timeout
建议:
> 秒级合理超时。
具体根据供应商SLA。
---
# 第一百七十二章 Retry
只对:
> 明确可重试错误。
不要实名认证提交失败就无限重试。
避免重复请求和费用。
---
# 第一百七十三章 外部Provider适配层
建议:
```text
WechatAdapter
IdentityVerificationProvider
SmsProvider
ObjectStorageProvider
```
避免Service直接写供应商SDK。
后续更换服务商更容易。
---
# 第一百七十四章 Provider配置
后台不要直接暴露Secret。
使用部署配置。
运营后台最多看到:
```text
实名认证服务:正常
```
---
# 第一百七十五章 微信小程序发布
小程序前端发布流程:
```text
开发版本
↓
体验版
↓
业务验收
↓
提交审核
↓
正式发布
```
---
# 第一百七十六章 小程序API兼容
由于小程序审核和后端发布时间可能不同:
> API必须保持一定向后兼容。
不能后端一升级:
> 旧小程序立即全部坏。
---
# 第一百七十七章 API兼容策略
V1:
```text
/api/v1
```
增加字段:
> 兼容。
删除/重命名字段:
> 谨慎。
重大破坏:
> `/api/v2`
---
# 第一百七十八章 小程序最低版本控制
可以在:
```text
/app/config
```
返回:
```text
minimumSupportedVersion
latestVersion
```
---
# 第一百七十九章 强制升级
微信小程序升级机制不同于APP。
可以提示:
> 当前版本过旧,请重新打开小程序获取最新版本。
但不要频繁使用。
---
# 第一百八十章 后台前端升级
Admin Web是静态资源。
发布后:
> 刷新获取新版本。
需要注意浏览器缓存。
---
# 第一百八十一章 Static Assets
文件名使用Hash:
```text
app.a87f91.js
```
避免老缓存。
---
# 第一百八十二章 后台版本不一致
前端可以在API发现:
```text
CLIENT_VERSION_TOO_OLD
```
提示刷新。
---
# 第一百八十三章 安全补丁升级
依赖包定期检查:
- 后端Framework
- Node依赖
- Nginx
- PostgreSQL
- Redis
- Docker
---
# 第一百八十四章 不自动升级生产主版本
例如:
> 数据库大版本。
必须:
```text
评估
↓
测试
↓
备份
↓
Staging
↓
生产维护窗口
```
---
# 第一百八十五章 小版本安全补丁
仍应:
> 先Test/Staging。
不要生产服务器自动apt upgrade所有软件。
---
# 第一百八十六章 Dependency Lock
必须有:
- package-lock
- pnpm-lock
- Maven/Gradle固定依赖
保证构建可重复。
---
# 第一百八十七章 镜像基础版本
不要长期:
```text
node:latest
```
固定:
> 主版本/明确镜像Tag。
---
# 第一百八十八章 容器运行安全
建议:
- 非root运行
- 只读文件系统(可行处)
- 最小权限
- 不挂Docker Socket
- 不把Secret写镜像
---
# 第一百八十九章 防火墙
公网只开放:
```text
80
443
```
SSH:
> 仅管理IP/VPN。
PostgreSQL:
> 不公网。
Redis:
> 不公网。
---
# 第一百九十章 SSH管理
建议:
- SSH Key
- 禁止密码登录(条件允许)
- 不允许root直接登录
- 管理IP限制
---
# 第一百九十一章 管理员系统和服务器权限分离
后台platform_admin:
> 不等于服务器root。
运营人员不需要SSH权限。
---
# 第一百九十二章 云账号权限
采用:
> 最小权限。
开发人员:
> 不自动拥有生产云账号Owner。
---
# 第一百九十三章 生产变更权限
建议:
- 技术负责人
- 指定运维
执行。
重要变更:
> 留记录。
---
# 第一百九十四章 域名与证书管理
必须记录:
```text
域名注册商
证书
负责人
到期时间
```
域名过期是非常常见但严重的事故。
---
# 第一百九十五章 证书到期告警
建议提前:
```text
30天
15天
7天
```
提醒。
---
# 第一百九十六章 数据库密码轮换
人员变化或怀疑泄露:
> 立即轮换。
定期轮换频率根据安全政策。
---
# 第一百九十七章 API Secret轮换
Provider Adapter应支持:
> 新旧Secret短期切换。
减少停机。
---
# 第一百九十八章 JWT/Token Key轮换
设计:
> key version/kid。
未来可以平滑轮换。
V1如果实现简单,也至少保留替换能力。
---
# 第一百九十九章 生产故障分级
建议:
```text
SEV1
SEV2
SEV3
```
---
# 第二百章 SEV1
例如:
```text
全站不可用
数据库损坏
大规模数据泄露
严重权限绕过
Match大量错误生成
```
---
# 第二百零一章 SEV1处置流程
```text
发现
↓
停止扩大影响
↓
必要时维护模式/Feature Flag
↓
保护数据
↓
定位
↓
修复/回滚
↓
恢复
↓
验证
↓
事故复盘
```
---
# 第二百零二章 SEV2
例如:
- 聊天不可用
- 推荐不可用
- 活动报名异常
- 实名第三方异常
核心平台部分可用。
---
# 第二百零三章 SEV3
例如:
- 某统计延迟
- 非核心通知失败
- 局部后台页面Bug
---
# 第二百零四章 故障第一原则
> **先停止错误扩散,再追求恢复功能。**
例如Match逻辑错:
> 先关闭Like。
不要继续生成错误关系。
---
# 第二百零五章 数据事故
如果发现数据写错:
> 禁止直接批量手改。
先:
- 备份
- 确认影响范围
- Dry Run修复脚本
- 执行
- 验证
---
# 第二百零六章 故障Runbook
建议至少建立:
```text
API全挂
数据库不可连接
Redis故障
对象存储故障
微信登录异常
实名认证异常
磁盘满
证书过期
Match异常
消息异常
权限事故
```
---
# 第二百零七章 Runbook格式
每个包含:
```text
症状
检查步骤
临时措施
恢复方法
升级联系人
验证方式
```
---
# 第二百零八章 数据库故障Runbook
示例:
```text
1 检查数据库状态
2 检查连接数
3 检查磁盘
4 检查慢查询/锁
5 必要时只读/维护
6 恢复或切换
7 核心数据校验
```
---
# 第二百零九章 Redis故障Runbook
```text
1 判断是否核心业务受影响
2 Restart/替换Redis
3 Session影响评估
4 清缓存
5 用户重新登录
6 检查推荐/未读恢复
```
---
# 第二百一十章 Object Storage故障
降级:
- 文字功能保留
- 暂停图片上传
- 已有图片暂时显示失败占位
不需要:
> 全平台维护。
---
# 第二百一十一章 微信服务异常
提示:
> 微信服务暂时异常,请稍后重试。
记录Provider错误。
---
# 第二百一十二章 实名服务故障
可以:
> 暂停新实名认证。
已有已实名用户:
> 正常使用。
---
# 第二百一十三章 风控系统故障
核心权限:
- Block
- AccountStatus
仍必须工作。
辅助关键词检测异常:
> 可降级。
---
# 第二百一十四章 统计系统故障
Analytics失败:
> 不影响用户Match/Chat。
Dashboard提示:
> 数据暂时无法更新。
---
# 第二百一十五章 事故复盘
SEV1/重要SEV2后必须形成:
```text
发生什么
为什么
影响谁
为什么监控没提前发现
怎么修
怎么防止再次发生
```
---
# 第二百一十六章 复盘不是追责会议
目标:
> 改系统和流程。
例如:
“开发操作失误”
不是根因。
应继续问:
> 为什么一个人的失误能够直接影响生产?
---
# 第二百一十七章 版本升级节奏
V1稳定后:
建议:
```text
Patch
按需
Minor
按业务周期
Major
谨慎
```
不要:
> 每天生产升级核心结构。
---
# 第二百一十八章 高频小版本
如果团队初期快速迭代:
可以:
> 每周固定窗口。
比随时上线更可控。
---
# 第二百一十九章 大型活动冻结期
活动前:
> 24~48小时建议冻结高风险大改动。
只允许:
> 紧急Hotfix。
---
# 第二百二十章 数据库维护窗口
如需:
- 大索引
- 大版本升级
提前通知运营。
---
# 第二百二十一章 生产数据初始化
首次上线必须:
```text
Migration
↓
基础字典
↓
系统角色
↓
系统权限
↓
平台组织
↓
首个管理员
↓
系统基础配置
```
---
# 第二百二十二章 Seed原则
只Seed:
- 字典
- Role
- Permission
- 基础配置
不要Seed:
> 测试用户到生产。
---
# 第二百二十三章 首个Super Admin
通过:
> 安全部署脚本/一次性初始化。
不能默认:
```text
账号和密码由部署环境安全提供,不写入文档
```
---
# 第二百二十四章 默认密码
如果系统生成临时密码:
> 首次登录强制修改。
---
# 第二百二十五章 生产启动后检查
第一次:
```text
健康检查
↓
Admin登录
↓
微信登录
↓
测试实名环境检查
↓
文件上传
↓
推荐
↓
WebSocket
↓
数据库备份
```
---
# 第二百二十六章 监控上线必须早于用户推广
不能:
> 用户都来了才开始装监控。
---
# 第二百二十七章 第一场活动前额外检查
```text
Activity API
Registration
Check-in
Admin Login
Volunteer Account
Mobile Network
Manual Check-in
Backup Plan
```
---
# 第二百二十八章 运维文档
建议目录:
```text
docs/ops/
├── architecture.md
├── deployment.md
├── environment.md
├── backup-restore.md
├── monitoring.md
├── incident-runbook.md
├── release.md
└── disaster-recovery.md
```
---
# 第二百二十九章 部署脚本建议
```text
scripts/
├── deploy.sh
├── rollback.sh
├── backup-db.sh
├── restore-db.sh
├── health-check.sh
└── rebuild-metrics.sh
```
根据操作系统调整。
---
# 第二百三十章 Deploy Script原则
必须:
- `set -e`
- 检查镜像
- 检查环境
- 记录版本
- 健康检查
- 失败退出
---
# 第二百三十一章 Rollback Script
必须明确:
> 回哪个版本。
例如:
```text
./rollback.sh 1.0.0
```
不能:
> “回上一版”但系统不知道上一版是谁。
---
# 第二百三十二章 Backup Script
运行后:
- 生成备份
- 校验
- 上传异地
- 记录成功
- 失败告警
---
# 第二百三十三章 Restore Script
默认:
> 不允许直接恢复覆盖生产。
应要求:
```text
target database
backup file
confirmation
```
防止误操作。
---
# 第二百三十四章 生产访问最小化
普通开发:
> 不需要每天SSH生产。
系统可通过:
- 监控
- 日志
- Admin
完成日常工作。
---
# 第二百三十五章 日志查询工具
初期:
> Docker logs + 集中日志/云日志
足够。
用户量增加后:
再考虑:
> Loki等轻量日志系统。
---
# 第二百三十六章 不建议V1自建ELK
因为:
- 内存高
- 运维复杂
- 当前数据规模不需要
---
# 第二百三十七章 Metrics与Logs区分
Metrics:
> 看系统是不是出问题。
Logs:
> 查为什么出问题。
Audit:
> 查谁做了什么。
三者不能混为一体。
---
# 第二百三十八章 生产数据库直接查询
普通运营:
> 禁止。
技术人员如必须:
- 只读账号
- 受控访问
- 记录操作
---
# 第二百三十九章 生产数据修复
使用:
> 专用脚本。
不要:
```text
UPDATE users SET ...
```
直接靠手工SQL长期处理。
---
# 第二百四十章 Schema Ownership
数据库结构修改:
> 只能Migration。
Application User:
> 无ALTER TABLE权限。
---
# 第二百四十一章 成本控制原则
V1成本重点投入:
```text
稳定服务器
数据库
对象存储
备份
HTTPS
```
暂时不花重金:
- Kubernetes
- 大型APM
- 数据仓库
- 搜索集群
---
# 第二百四十二章 初期资源建议原则
不要预估成:
> 百万用户平台。
按照:
> 数千~数万用户可扩展
设计即可。
具体CPU/内存规格应根据最终技术栈和压测结果确定。
---
# 第二百四十三章 一个合理的扩容路径
```text
阶段1
单Backend
+
PostgreSQL
+
Redis
阶段2
Backend x2
+
负载均衡
阶段3
PostgreSQL升级规格
+
Redis独立
阶段4
读写压力明显后
再考虑进一步架构调整
```
---
# 第二百四十四章 不提前分布式
因为V1真正风险不是:
> 扛不住百万QPS。
而是:
- 权限错
- Match错
- 数据丢
- 活动现场不可用
技术投入应优先解决这些。
---
# 第二百四十五章 运维权限分层
建议:
```text
Cloud Admin
Deployment Operator
Database Admin
Read-only Observer
```
小团队可兼任。
但权限思想保留。
---
# 第二百四十六章 云主账号
不要作为:
> 日常登录账号。
启用:
- MFA
- 强保护
日常使用子账号。
---
# 第二百四十七章 Secret泄露事故
一旦发现:
```text
Git中提交Secret
```
不能只:
> 删除Commit里的Secret。
必须:
> 立即Rotate。
因为历史可能已经泄露。
---
# 第二百四十八章 数据库备份恢复验收标准
必须证明:
```text
备份文件存在
↓
成功恢复新数据库
↓
Backend能连接
↓
核心E2E数据正常
```
才算:
> Backup可用。
---
# 第二百四十九章 发布验收标准
每次生产上线后:
```text
/version正确
/health正确
Login正确
推荐正确
消息正确
Admin正确
监控无异常
```
---
# 第二百五十章 生产变更记录
每次记录:
```text
版本
时间
执行人
Migration
配置变化
结果
是否回滚
```
---
# 第二百五十一章 维护公告
如计划停机:
提前:
> 在小程序和后台提示。
不需要复杂公告系统。
可以通过:
> system notice/config。
---
# 第二百五十二章 用户端降级页面
至少:
```text
维护中
网络异常
服务暂不可用
```
不能只显示:
> 请求失败 -500。
---
# 第二百五十三章 后台故障页面
管理员看到:
> 当前服务暂时不可用,RequestId xxx。
方便反馈技术人员。
---
# 第二百五十四章 第三方依赖降级矩阵
| 服务 | 故障影响 | 降级 |
|---|---|---|
| 微信登录 | 新登录受影响 | 已登录用户继续 |
| 实名服务 | 新实名受影响 | 已实名用户正常 |
| 对象存储 | 图片受影响 | 文字业务继续 |
| Redis | Cache/Session部分影响 | DB核心业务保留 |
| Analytics | 统计页面 | 核心婚恋不受影响 |
---
# 第二百五十五章 核心依赖矩阵
PostgreSQL:
> 核心依赖。
如果不可用:
> 应进入维护模式/保护状态。
---
# 第二百五十六章 数据一致性优先
如果数据库出现异常:
不要为了:
> 页面继续“看起来能用”
而允许本地/Redis继续写业务。
---
# 第二百五十七章 上线后容量评估
每月记录:
```text
用户增长
数据库增长
消息增长
对象存储增长
峰值连接
峰值QPS
```
---
# 第二百五十八章 什么时候考虑架构升级
满足以下情况再考虑:
```text
单实例Backend成为明显瓶颈
数据库规格已明显不足
实时连接量增长
统计查询影响主业务
部署频率与团队规模显著增加
```
---
# 第二百五十九章 不以“感觉用户以后会很多”作为升级依据
必须:
> 基于监控数据。
---
# 第二百六十章 V1明确不采用
```text
Kubernetes
Kafka
RabbitMQ(除非后期确有任务需求)
Elasticsearch
ClickHouse
Neo4j
Service Mesh
微服务拆分
多活数据库
复杂DevOps平台
```
---
# 第二百六十一章 V1推荐的最小可靠技术组合
```text
Nginx
+
Docker Compose
+
Backend Modular Monolith
+
PostgreSQL
+
Redis
+
Private Object Storage
+
云监控/Prometheus
+
数据库自动备份
+
Git CI/CD
```
足够支持V1长期稳定运行。
---
# 第二百六十二章 WorkBuddy实现要求:部署文件
代码仓库必须提供:
```text
docker-compose.yml
docker-compose.staging.yml
.env.example
Dockerfile
nginx/
scripts/
docs/ops/
```
---
# 第二百六十三章 WorkBuddy实现要求:健康检查
必须实现:
```text
/health/live
/health/ready
/version
```
---
# 第二百六十四章 WorkBuddy实现要求:Migration
必须在CI和部署流程中:
> 自动检测Migration。
禁止:
> 应用启动时偷偷自动修改生产结构且不可追踪。
---
# 第二百六十五章 WorkBuddy实现要求:日志
所有后端日志:
> 结构化。
包含:
```text
requestId
level
module
message
```
---
# 第二百六十六章 WorkBuddy实现要求:Graceful Shutdown
Backend收到:
> SIGTERM
应:
- 停止接新请求
- 完成当前合理请求
- 关闭DB连接
- 关闭Redis
- 关闭WebSocket
避免部署时大量异常。
---
# 第二百六十七章 WorkBuddy实现要求:Readiness
Migration未完成或数据库不可连接:
```text
ready = false
```
---
# 第二百六十八章 WorkBuddy实现要求:Scheduler
所有定时任务:
- 有名称
- 有日志
- 幂等
- 可手工补跑
- 失败可告警
---
# 第二百六十九章 WorkBuddy实现要求:对象存储抽象
不要硬编码供应商SDK到业务层。
接口:
```text
ObjectStorageService
```
以后可以切换国内云厂商。
---
# 第二百七十章 WorkBuddy实现要求:Provider抽象
同样:
```text
IdentityProvider
WechatProvider
SmsProvider
```
---
# 第二百七十一章 WorkBuddy实现要求:配置检查
应用启动时检查必要配置。
缺:
```text
DATABASE_URL
JWT_SECRET
```
应:
> Fail Fast。
不是启动后用户调用才发现。
---
# 第二百七十二章 WorkBuddy实现要求:生产模式
Production启动时:
- 禁Debug
- 禁Swagger公开访问(或鉴权)
- 禁测试接口
- 禁Mock实名
- 禁默认密码
---
# 第二百七十三章 Swagger/OpenAPI
生产是否开放:
建议:
> 后台鉴权或仅内网。
不能公开暴露完整管理API文档。
---
# 第二百七十四章 测试接口
例如:
```text
/test/create-user
/test/mock-match
```
生产:
> 完全不存在或强制禁用。
---
# 第二百七十五章 运维最终验收清单
```text
□ Docker镜像可重复构建
□ Compose可启动
□ Production Secret不进Git
□ HTTPS正常
□ WSS正常
□ PostgreSQL非公网
□ Redis非公网
□ Object Storage Private
□ Health Check正常
□ RequestId正常
□ 日志脱敏
□ 监控正常
□ 告警正常
□ 数据库备份正常
□ 恢复演练完成
□ Migration流程完成
□ Rollback可执行
□ Feature Flag可用
□ 运维文档齐全
```
---
# 第二百七十六章 备份最终验收清单
```text
□ 每日数据库备份
□ 备份存储位置独立
□ 备份访问受限
□ 备份加密
□ 备份失败告警
□ 对象存储保护
□ 配置在Git
□ Secret有安全备份
□ 实际Restore验证
```
---
# 第二百七十七章 发布最终验收清单
```text
□ CI通过
□ Test通过
□ Staging通过
□ Migration验证
□ 生产备份
□ 发布版本明确
□ Release Notes
□ Smoke Test
□ 监控无异常
□ 回滚版本准备
```
---
# 第二百七十八章 故障恢复最终验收
至少能够处理:
```text
应用服务器损坏
Redis损坏
数据库恢复
对象存储异常
证书异常
微信登录异常
实名服务异常
错误版本上线
```
---
# 第二百七十九章 V1部署与运维核心原则
必须坚持:
> **生产环境必须可以重新搭出来,而不是只有某个人知道怎么维护。**
> **数据库是核心事实源,Redis只是加速。**
> **用户文件必须进入私有对象存储,不放应用服务器本地。**
> **生产部署必须使用固定版本镜像。**
> **生产数据库禁止手工随意改表。**
> **所有结构变化必须Migration。**
> **备份必须真正做过恢复验证。**
> **应用升级必须能回滚。**
> **重要功能必须能够通过Feature Flag快速关闭。**
> **出现严重错误时优先保护数据,而不是强撑服务可用。**
> **运维系统应该简单到一个普通技术人员按照文档也能恢复,而不是高度依赖某一个开发者。**
---
# 第二百八十章 最终部署架构
V1推荐最终结构:
```text
Internet / WeChat
│
HTTPS/WSS
│
┌───────┐
│ Nginx │
└───┬───┘
│
Backend Container
Modular Monolith
│
┌──────────────────┼──────────────────┐
│ │ │
↓ ↓ ↓
PostgreSQL Redis Object Storage
Core Truth Cache Private Files
│
↓
Automated Backup
│
↓
Independent Storage
Monitoring
│
├── Infrastructure
├── Application
├── Business
└── Security
CI/CD
│
↓
Build Image
↓
Staging
↓
Production
↓
Monitor
↓
Rollback if needed
```
---
# 第二百八十一章 最终结论
丹阳公益婚恋服务平台V1.0不需要一套“看起来很高级”的大型技术基础设施。
真正需要的是:
> **任何一个服务器坏了,系统能重新部署。**
> **任何一个版本出问题,能够回退。**
> **数据库损坏,有备份可以恢复。**
> **Redis丢失,不会丢核心业务。**
> **对象存储出现问题,不会让数据库关系失真。**
> **上线后出现异常,监控能够及时发现。**
> **开发人员离开后,其他人仍然可以按文档维护。**
因此V1部署策略可以概括为:
> **架构尽量简单,数据保护必须认真;部署可以轻量,备份不能轻量;升级可以快速,回滚必须可靠。**