# AI临床研究平台 - 阿里云部署架构总览 > **文档版本:** v1.0 > **创建日期:** 2025-12-14 > **目标环境:** 阿里云 SAE + RDS PostgreSQL 15 + OSS > **架构类型:** 云原生 Serverless + 容器化微服务 > **适用团队:** 1-2人初创团队 → 10人成长团队 --- ## 📋 目录 1. [架构全景图](#架构全景图) 2. [5个核心模块关系](#5个核心模块关系) 3. [模块与阿里云服务映射](#模块与阿里云服务映射) 4. [开发环境与部署环境](#开发环境与部署环境) 5. [Docker版本管理策略](#docker版本管理策略) 6. [线上故障快速修复](#线上故障快速修复) 7. [部署文档导航](#部署文档导航) --- ## 架构全景图 ### 1. 逻辑架构(用户视角) ``` ┌─────────────────────────────────────────────────────────────────────┐ │ 用户浏览器(Browser) │ │ https://your-domain.com │ └────────────────────────────────┬────────────────────────────────────┘ │ ┌────────────▼───────────────┐ │ 前端 SPA (React 19) │ │ - 用户界面 │ │ - 路由管理 │ │ - API调用 │ └────────────┬───────────────┘ │ ┌──────────────────┼──────────────────┐ │ │ │ ┌─────────▼──────┐ ┌───────▼───────┐ ┌──────▼──────────┐ │ Node.js后端 │ │ Python微服务 │ │ Dify RAG平台 │ │ (Fastify) │ │ (FastAPI) │ │ (知识库检索) │ │ │ │ │ │ │ │ - 业务逻辑 │ │ - PDF解析 │ │ - 文档上传 │ │ - 权限控制 │ │ - 数据清洗 │ │ - 向量检索 │ │ - API聚合 │ │ - 文件提取 │ │ - LLM对话 │ └────────┬───────┘ └───────┬───────┘ └──────┬──────────┘ │ │ │ │ │ │ └──────────────────┼──────────────────┘ │ ┌───────────▼────────────┐ │ PostgreSQL 15 数据库 │ │ (RDS) │ │ │ │ - 10个Schema隔离 │ │ - pg-boss任务队列 │ │ - Postgres-Only架构 │ └────────────────────────┘ ``` ### 2. 物理架构(阿里云资源) ``` ┌───────────────────────────────────────────────────────────────────────────┐ │ 阿里云 VPC(专有网络) │ │ 172.16.0.0/12(内网隔离) │ ├───────────────────────────────────────────────────────────────────────────┤ │ │ │ ┌─────────────────────────────────────────────────────────────────┐ │ │ │ SAE (Serverless Application Engine) │ │ │ │ 容器化应用部署平台 │ │ │ ├─────────────────────────────────────────────────────────────────┤ │ │ │ │ │ │ │ ┌───────────────┐ ┌───────────────┐ ┌──────────────────┐ │ │ │ │ │ 前端Nginx │ │ Node.js后端 │ │ Python微服务 │ │ │ │ │ │ 容器应用 │ │ 容器应用 │ │ 容器应用 │ │ │ │ │ ├───────────────┤ ├───────────────┤ ├──────────────────┤ │ │ │ │ │ Nginx 1.25 │ │ Node.js 22 │ │ Python 3.11 │ │ │ │ │ │ React构建产物 │ │ Fastify 5 │ │ FastAPI 0.104 │ │ │ │ │ │ 健康检查/路由 │ │ Prisma 6 │ │ PyMuPDF/Polars │ │ │ │ │ └───────┬───────┘ └───────┬───────┘ └────────┬─────────┘ │ │ │ │ │ │ │ │ │ │ │ │ 内网调用 │ 内网调用 │ │ │ │ │ └──────────────────┴───────────────────┘ │ │ │ │ │ │ │ │ └─────────────────────────────┼─────────────────────────────────┘ │ │ │ │ │ ┌──────────────────────────────────────────────────────────┐ │ │ │ ⭐ NAT网关 + EIP(公网出口,必需) │ │ │ ├──────────────────────────────────────────────────────────┤ │ │ │ - 为SAE提供公网访问能力 │ │ │ │ - 后端调用DeepSeek/OpenAI API │ │ │ │ - Python下载公网PDF │ │ │ │ - npm install公网依赖 │ │ │ │ - 成本:NAT网关¥60/月 + EIP流量费 │ │ │ │ - ⚠️ 没有NAT网关,AI功能全部超时! │ │ │ └──────────────────────────────────────────────────────────┘ │ │ │ │ │ ┌─────────────────────────────▼──────────────────────────┐ │ │ │ RDS PostgreSQL 15(云数据库) │ │ │ │ rds.pg.s2.large (2核4GB) │ │ │ ├────────────────────────────────────────────────────────┤ │ │ │ - 数据库名:ai_clinical_research │ │ │ │ - 用户:aiclinical_rw(应用专用账号) │ │ │ │ - 内网地址:rm-xxxxx.pg.rds.aliyuncs.com:5432 │ │ │ │ - 自动备份:每天凌晨2点 + 日志备份(PITR) │ │ │ │ - 白名单:172.16.0.0/12(SAE的VPC网段) │ │ │ └────────────────────────────────────────────────────────┘ │ │ │ │ ┌──────────────────────────────────────────────────────────┐ │ │ │ OSS (Object Storage Service) 对象存储 │ │ │ │ Bucket: aiclinical-data-prod │ │ │ ├──────────────────────────────────────────────────────────┤ │ │ │ - 用户上传文件(PDF、Word、Excel) │ │ │ │ - 文献数据(ASL模块) │ │ │ │ - 数据清洗结果(DC模块) │ │ │ │ - 数据库备份归档(可选) │ │ │ │ - 访问方式:SDK(内网免流量费) │ │ │ └──────────────────────────────────────────────────────────┘ │ │ │ └───────────────────────────────────────────────────────────────────────┘ ┌───────────────────────────────────────────────────────────────────────────┐ │ 独立 ECS 服务器(Dify部署) │ │ ecs.c6.xlarge (4核8GB) │ ├───────────────────────────────────────────────────────────────────────────┤ │ ┌──────────────────────────────────────────────────────────────┐ │ │ │ Dify RAG 平台 (Docker Compose) │ │ │ ├──────────────────────────────────────────────────────────────┤ │ │ │ - Dify API (dify/api:0.6.13) │ │ │ │ - Dify Web (dify/web:0.6.13) │ │ │ │ - PostgreSQL 15 (postgres:15-alpine,Dify专用数据库) │ │ │ │ - Redis (redis:6-alpine,Dify缓存) │ │ │ │ - Weaviate (向量数据库) │ │ │ │ - Nginx (路由层,处理CORS) │ │ │ │ - Sandbox (代码执行沙箱) │ │ │ │ │ │ │ │ 内网地址:http://172.16.x.x(通过VPC与SAE互联) │ │ │ └──────────────────────────────────────────────────────────────┘ │ │ │ └───────────────────────────────────────────────────────────────────────────┘ ``` ### 3. 数据流向图 ``` 用户上传文件 │ ├──► 前端 (React) │ │ │ ├──► /api/v1/pkb/documents (上传到知识库) │ │ │ │ │ ├──► Node.js后端 │ │ │ │ │ │ │ ├──► OSS (存储原始文件) │ │ │ └──► Dify API (创建文档向量) │ │ │ │ │ │ │ └──► Weaviate (存储向量) │ │ │ │ │ └──► RDS (存储元数据) │ │ │ ├──► /api/v1/asl/literatures (文献筛选) │ │ │ │ │ ├──► Node.js后端 │ │ │ │ │ │ │ ├──► Python微服务 (PDF解析) │ │ │ │ │ │ │ │ │ └──► OSS (读取PDF) │ │ │ │ │ │ │ └──► RDS (存储文献数据) │ │ │ │ │ └──► 返回解析结果 │ │ │ └──► /api/v1/dc/extraction (数据清洗) │ │ │ ├──► Node.js后端 │ │ │ │ │ ├──► Python微服务 (Polars数据处理) │ │ │ │ │ │ │ └──► OSS (读取Excel/CSV) │ │ │ │ │ └──► RDS (存储清洗结果) │ │ │ └──► 返回清洗结果 │ └──► 展示结果 ``` --- ## 5个核心模块关系 ### 1. 模块依赖关系图 ``` ┌─────────────────────────────────────────────────────────────────┐ │ 核心依赖层级 (从下到上) │ └─────────────────────────────────────────────────────────────────┘ L4: 用户界面层 ┌──────────────────────────────────────────────────────┐ │ 前端 (React 19 + Vite 7) │ │ - 调用 Node.js后端的 REST API │ │ - 不直接调用 Python微服务和Dify │ │ - 通过反向代理 (/api/) 路由到后端 │ └──────────────────────────────────────────────────────┘ ▲ │ HTTP/HTTPS │ ───────────────────────────────────────────────────────── L3: 业务逻辑层 ┌──────────────────────────────────────────────────────┐ │ Node.js 后端 (Fastify + Prisma) │ │ - 业务逻辑聚合 │ │ - 权限控制 │ │ - 调用 Python微服务 (内网HTTP) │ │ - 调用 Dify API (内网HTTP) │ │ - 数据库访问 (Prisma ORM) │ └──────────────────────────────────────────────────────┘ ▲ ▲ ▲ │ │ │ │ (内网) │ (内网) │ (Prisma) │ │ │ ┌──────┴────────┐ ┌──────┴──────┐ ┌────▼──────┐ │ Python微服务 │ │ Dify平台 │ │ PostgreSQL│ └───────────────┘ └─────────────┘ └───────────┘ ───────────────────────────────────────────────────────── L2: 能力支撑层 ┌────────────────────────────┐ ┌────────────────────────────┐ │ Python 微服务 │ │ Dify RAG 平台 │ │ (FastAPI + PyMuPDF) │ │ (知识库 + LLM) │ ├────────────────────────────┤ ├────────────────────────────┤ │ - PDF解析 (ASL模块) │ │ - 文档上传分块 │ │ - Docx/Txt提取 (ASL) │ │ - Embedding向量化 │ │ - 数据清洗 (DC模块) │ │ - 向量检索 │ │ - Polars数据处理 │ │ - LLM对话生成 │ │ - OCR识别 (Nougat) │ │ - RAG流程编排 │ │ │ │ │ │ 依赖: │ │ 依赖: │ │ - OSS (读取文件) │ │ - Weaviate (向量存储) │ │ - RDS (存储结果,可选) │ │ - PostgreSQL (Dify专用) │ │ │ │ - Redis (Dify缓存) │ └────────────────────────────┘ └────────────────────────────┘ ▲ ▲ │ │ └────────────┬───────────────────┘ │ ───────────────────────────────────────────────────────── L1: 基础设施层 ┌────────────────────┐ ┌────────────────┐ ┌──────────────┐ │ PostgreSQL 15 │ │ OSS对象存储 │ │ Redis (可选) │ │ (RDS) │ │ (文件存储) │ │ (Dify专用) │ ├────────────────────┤ ├────────────────┤ ├──────────────┤ │ - 10个Schema隔离 │ │ - PDF文件 │ │ - Dify缓存 │ │ - pg-boss任务队列 │ │ - Word/Excel │ │ - Dify会话 │ │ - 用户数据 │ │ - 文献数据 │ │ │ │ - 业务数据 │ │ - 清洗结果 │ │ (初期不需要 │ │ - Prisma ORM访问 │ │ - SDK访问 │ │ Redis,可用 │ │ │ │ - 内网免流量 │ │ Postgres替代)│ └────────────────────┘ └────────────────┘ └──────────────┘ ``` ### 2. 模块间调用关系表 | 调用方 | 被调用方 | 调用方式 | 调用目的 | 网络 | |--------|---------|---------|---------|------| | **前端** | Node.js后端 | HTTP REST API | 所有业务功能 | 公网(HTTPS) | | **Node.js后端** | Python微服务 | HTTP REST API | PDF解析、数据清洗 | 内网(VPC) | | **Node.js后端** | Dify API | HTTP REST API | 知识库管理、RAG检索 | 内网(VPC) | | **Node.js后端** | PostgreSQL | Prisma ORM | 数据CRUD、事务 | 内网(VPC) | | **Node.js后端** | OSS | SDK (ali-oss) | 文件上传/下载 | 内网(VPC) | | **Python微服务** | OSS | SDK (oss2) | 读取PDF/Excel | 内网(VPC) | | **Python微服务** | PostgreSQL | 可选(直接SQL) | 读取配置数据 | 内网(VPC) | | **Dify** | Weaviate | gRPC | 向量存储/检索 | 本地(Dify内部) | | **Dify** | PostgreSQL | 原生驱动 | Dify元数据 | 本地(Dify内部) | | **Dify** | Redis | 原生驱动 | Dify缓存 | 本地(Dify内部) | **关键原则:** - ✅ **单一入口**:前端只调用 Node.js后端,不直接调用其他服务 - ✅ **内网通信**:SAE内部服务通过内网互联(免流量费,低延迟) - ✅ **服务隔离**:Dify独立部署在ECS,通过内网暴露API - ✅ **数据持久化**:核心数据统一存储在RDS,文件存储在OSS ### 3. 模块责任边界 | 模块 | 核心职责 | 不负责 | |------|---------|--------| | **前端** | - 用户交互
- 页面渲染
- 路由管理
- API调用 | ❌ 业务逻辑
❌ 权限校验
❌ 直接访问数据库/OSS | | **Node.js后端** | - 业务逻辑聚合
- 权限控制
- API网关
- 数据库访问
- 调度微服务 | ❌ PDF解析
❌ 数据清洗
❌ 向量检索 | | **Python微服务** | - PDF解析
- 文档提取
- 数据清洗
- OCR识别 | ❌ 业务逻辑
❌ 权限控制
❌ 数据库CRUD | | **Dify平台** | - 知识库管理
- 向量存储
- RAG检索
- LLM对话 | ❌ 用户认证
❌ 业务数据存储
❌ 权限管理 | | **PostgreSQL** | - 业务数据持久化
- 事务管理
- 任务队列(pg-boss) | ❌ 文件存储
❌ 缓存(可选) | | **OSS** | - 文件存储
- 静态资源
- 备份归档 | ❌ 结构化数据
❌ 实时计算 | --- ## 模块与阿里云服务映射 ### 1. 服务映射表 | 核心模块 | 阿里云服务 | 规格配置 | 成本估算 | 部署文档 | |---------|-----------|---------|---------|---------| | **前端 (React)** | SAE容器实例 | 0.5核1GB × 1实例 | ¥50/月 | [06-前端Nginx-SAE容器部署指南](./06-前端Nginx-SAE容器部署指南.md) | | **Node.js后端** | SAE容器实例 | 1核2GB × 2实例(弹性) | ¥200/月 | [05-Node.js后端-SAE容器部署指南](./05-Node.js后端-SAE容器部署指南.md) | | **Python微服务** | SAE容器实例 | 1核2GB × 1实例(⚠️ 如OOM升至4GB) | ¥100-200/月 | [04-Python微服务-SAE容器部署指南](./04-Python微服务-SAE容器部署指南.md) | | **Dify平台** | ECS服务器 | 4核8GB(独立) | ¥300/月 | [03-Dify-ECS部署完全指南](./03-Dify-ECS部署完全指南.md) | | **PostgreSQL 15** | RDS PostgreSQL | 2核4GB (rds.pg.s2.large) | ¥400/月 | [PostgreSQL部署策略-摸底报告](./PostgreSQL部署策略-摸底报告.md) | | **文件存储** | OSS标准存储 | 按量付费(50GB) | ¥10/月 | (各模块文档中包含) | | **⭐ NAT网关** | NAT网关 + EIP | 小规格NAT + 按量EIP | ¥60-100/月 | ⚠️ **必需**(SAE访问公网) | | **容器镜像** | ACR容器镜像仓库 | 个人版(免费) | ¥0/月 | (各模块文档中包含) | | **VPC网络** | VPC专有网络 | 默认配置 | ¥0/月 | (各模块文档中包含) | | **域名/CDN** | (可选)未来配置 | - | ¥50/月 | - | **总成本估算:** ¥1,200-1,350/月(初期配置,含NAT网关) ⚠️ **成本优化说明:** - NAT网关(¥100/月)是生产环境标配,不建议省略 - 替代方案:SAE绑定EIP(¥30-50/月,部分地域支持,稳定性较差)或ECS做SNAT(¥0,配置复杂,不推荐) - Python服务如遇OOM,需升级至4GB内存(增加¥100/月) ### 2. SAE与5个模块的关系 #### 2.1 SAE部署的模块(3个) ``` ┌────────────────────────────────────────────────────────────────┐ │ SAE (Serverless Application Engine) │ │ 弹性伸缩 + 按需付费 │ ├────────────────────────────────────────────────────────────────┤ │ │ │ ┌──────────────────┐ ┌──────────────────┐ ┌──────────────┐│ │ │ 前端Nginx容器 │ │ Node.js后端容器 │ │ Python容器 ││ │ ├──────────────────┤ ├──────────────────┤ ├──────────────┤│ │ │ 实例数:1 │ │ 实例数:2-10 │ │ 实例数:1-3 ││ │ │ CPU: 0.5核 │ │ CPU: 1核 │ │ CPU: 1核 ││ │ │ 内存: 1GB │ │ 内存: 2GB │ │ 内存: 2GB ││ │ │ 健康检查: / │ │ 健康检查: /health│ │ 健康检查: /health││ │ │ 自动伸缩: 关闭 │ │ 自动伸缩: 开启 │ │ 自动伸缩: 开启││ │ └──────────────────┘ └──────────────────┘ └──────────────┘│ │ │ │ 共同特性: │ │ ✅ Docker容器部署(镜像从ACR拉取) │ │ ✅ 内网互联(免流量费) │ │ ✅ 自动扩缩容(基于CPU/内存/QPS) │ │ ✅ 滚动发布(零停机部署) │ │ ✅ 健康检查(自动重启异常实例) │ │ ✅ 日志自动收集(stdout/stderr → SLS) │ │ ✅ 环境变量注入(DATABASE_URL等敏感信息) │ │ │ └────────────────────────────────────────────────────────────────┘ ``` **SAE的核心价值:** 1. **弹性伸缩**:流量高峰自动扩容,低谷自动缩容 2. **按需付费**:只为实际使用的资源付费 3. **零运维**:无需管理服务器,自动故障转移 4. **快速部署**:从镜像启动实例<30秒 #### 2.2 非SAE部署的模块(2个) | 模块 | 部署方式 | 原因 | |------|---------|------| | **Dify平台** | ECS + Docker Compose | - 服务复杂(7个容器)
- 需要稳定IP(内网调用)
- 独立数据库/Redis
- 不需要弹性伸缩 | | **PostgreSQL 15** | RDS托管服务 | - 企业级数据库
- 自动备份/PITR
- 高可用(主从)
- 无需自己运维 | ### 3. OSS与5个模块的关系 #### 3.1 OSS使用场景 | 模块 | 使用OSS的场景 | 读/写 | Bucket目录结构 | |------|--------------|-------|---------------| | **Node.js后端** | - 用户上传文件
- 文档管理
- 临时文件中转 | 读/写 | `/uploads/{userId}/{fileId}.pdf` | | **Python微服务** | - 读取PDF进行解析
- 读取Excel进行清洗
- 写入处理结果 | 读/写 | `/asl/literatures/`
`/dc/extracted/` | | **Dify平台** | - (可选)上传文档到OSS
- Dify内部使用本地存储 | 不使用 | - | | **前端** | - 不直接访问OSS
- 通过后端API上传/下载 | 不使用 | - | | **PostgreSQL** | - (可选)备份归档到OSS | 不使用 | `/backups/` | #### 3.2 OSS Bucket设计 ``` aiclinical-data-prod (Bucket名称) │ ├── uploads/ # 用户上传的原始文件 │ ├── {userId}/ │ │ ├── {fileId}.pdf │ │ ├── {fileId}.docx │ │ └── {fileId}.xlsx │ │ ├── asl/ # ASL智能文献模块 │ ├── literatures/ # 文献PDF │ │ └── {projectId}/{litId}.pdf │ ├── extracted/ # 提取的文本 │ │ └── {projectId}/{litId}.json │ │ ├── dc/ # DC数据清洗模块 │ ├── raw/ # 原始数据文件 │ │ └── {taskId}/data.xlsx │ ├── cleaned/ # 清洗后的数据 │ │ └── {taskId}/result.xlsx │ │ ├── pkb/ # PKB个人知识库模块 │ ├── documents/ # 知识库文档 │ │ └── {kbId}/{docId}.pdf │ │ └── backups/ # 数据库备份(可选) └── {date}/ai_clinical_research.sql.gz ``` **OSS配置要点:** - ✅ **内网访问**:SAE通过内网访问OSS(免流量费) - ✅ **权限控制**:使用RAM角色授权,不暴露AccessKey - ✅ **生命周期**:临时文件30天后自动删除 - ✅ **跨域配置**:如果前端直传,需配置CORS ### 4. RDS与5个模块的关系 #### 4.1 RDS访问权限 | 模块 | 数据库名称 | 访问用户 | 权限 | 连接方式 | |------|-----------|---------|------|---------| | **Node.js后端** | ai_clinical_research | aiclinical_rw | SELECT/INSERT/UPDATE/DELETE | Prisma ORM | | **Python微服务** | ai_clinical_research | aiclinical_rw(可选) | SELECT(只读配置) | psycopg2(可选) | | **Dify平台** | ❌ 不使用主RDS | - | - | Dify使用独立PostgreSQL | | **前端** | ❌ 不直接访问 | - | - | 通过后端API | | **PostgreSQL** | - | postgres(超级用户) | ALL | 仅用于迁移/备份 | **连接池配置:** ``` 总连接数:400(RDS默认) ├── Node.js后端:200 (2实例 × 10连接/实例,预留180) ├── Python微服务:50 (1实例 × 5连接/实例,预留45) ├── pg-boss:50 (后台任务) ├── 预留:100 (管理、备份、临时扩容) ``` --- ## 开发环境与部署环境 ### 1. 环境对比表 | 维度 | 本地开发环境 | 阿里云部署环境 | |------|-------------|---------------| | **前端** | Vite Dev Server (localhost:3000) | SAE Nginx容器 (HTTPS) | | **Node.js后端** | tsx watch (localhost:3001) | SAE容器 (内网 + 公网) | | **Python微服务** | uvicorn (localhost:8000) | SAE容器 (内网) | | **Dify平台** | Docker Compose (localhost) | ECS Docker Compose (内网) | | **PostgreSQL** | Docker (localhost:5432) | RDS (内网地址) | | **OSS** | 本地文件系统 (./uploads) | 阿里云OSS | | **Redis** | ❌ 不使用(Postgres-Only) | ❌ 不使用(Dify独立Redis) | ### 2. 开发与部署的平滑迁移 #### 2.1 配置管理策略 ``` 项目根目录/ │ ├── backend/ │ ├── .env.local # 本地开发配置(不提交Git) │ ├── .env.example # 配置模板(提交Git) │ └── src/config/env.ts # 配置加载逻辑 │ ├── frontend-v2/ │ ├── .env.local # 本地开发配置 │ ├── .env.production # 生产环境配置模板 │ └── vite.config.ts # Vite配置 │ └── extraction_service/ ├── .env.local # 本地开发配置 └── app/config.py # Python配置加载 ``` **配置加载优先级:** ``` 环境变量 > .env.local > .env > 代码默认值 ``` #### 2.2 环境变量对比 **本地开发 (`.env.local`):** ```bash # 数据库 DATABASE_URL=postgresql://postgres:postgres@localhost:5432/ai_clinical_research # 存储 STORAGE_TYPE=local LOCAL_STORAGE_DIR=./uploads # 缓存/队列 CACHE_TYPE=memory QUEUE_TYPE=memory # 微服务 DIFY_API_URL=http://localhost/v1 EXTRACTION_SERVICE_URL=http://localhost:8000 ``` **阿里云部署(SAE环境变量配置):** ```bash # 数据库(⚠️ 敏感信息,SAE加密存储) DATABASE_URL=postgresql://aiclinical_rw:强密码@rm-xxxxx.pg.rds.aliyuncs.com:5432/ai_clinical_research?connection_limit=10&pool_timeout=10 # 存储(OSS) STORAGE_TYPE=oss OSS_REGION=cn-hangzhou OSS_BUCKET=aiclinical-data-prod OSS_ACCESS_KEY_ID=LTAI5***(SAE环境变量) OSS_ACCESS_KEY_SECRET=***(SAE加密) # 缓存/队列(Postgres-Only) CACHE_TYPE=postgres QUEUE_TYPE=pgboss # 微服务(内网地址)⚠️ 使用内网IP,不要用.sae域名 DIFY_API_URL=http://172.16.x.x/v1 EXTRACTION_SERVICE_URL=http://172.16.x.x:8000 # ⚠️ 注意: # - 172.16.x.x 需要替换为实际的内网IP # - 获取方式:SAE控制台 > 应用详情 > 实例列表 > 查看内网IP # - ❌ 不要使用 .sae 或 .cluster.local 域名(K8s服务发现需要额外配置) # 生产环境标识 NODE_ENV=production ``` ### 3. 持续部署流程(CI/CD) #### 3.1 整体流程图 ``` ┌──────────────────────────────────────────────────────────────────┐ │ 开发者本地开发 │ │ 1. 修改代码 │ │ 2. 本地测试(npm run dev / pytest) │ │ 3. Git提交(git commit -m "feat: xxx") │ │ 4. 推送到远程仓库(git push origin main) │ └────────────────────────────┬─────────────────────────────────────┘ │ ▼ ┌──────────────────────────────────────────────────────────────────┐ │ CI/CD 流水线(未来:GitHub Actions) │ │ ┌────────────────────────────────────────────────────────────┐ │ │ │ Stage 1: 构建与测试 │ │ │ ├────────────────────────────────────────────────────────────┤ │ │ │ - npm install / pip install │ │ │ │ - npm run build / docker build │ │ │ │ - npm test / pytest │ │ │ │ - Lint检查 (eslint / flake8) │ │ │ └────────────────────────────────────────────────────────────┘ │ │ │ │ │ ▼ │ │ ┌────────────────────────────────────────────────────────────┐ │ │ │ Stage 2: Docker镜像构建 │ │ │ ├────────────────────────────────────────────────────────────┤ │ │ │ - docker build -t frontend:v1.2.3 │ │ │ │ - docker build -t backend:v1.2.3 │ │ │ │ - docker build -t python-service:v1.2.3 │ │ │ └────────────────────────────────────────────────────────────┘ │ │ │ │ │ ▼ │ │ ┌────────────────────────────────────────────────────────────┐ │ │ │ Stage 3: 推送到ACR容器镜像仓库 │ │ │ ├────────────────────────────────────────────────────────────┤ │ │ │ - docker tag ... registry.cn-hangzhou.aliyuncs.com/... │ │ │ │ - docker push registry.cn-hangzhou.aliyuncs.com/... │ │ │ └────────────────────────────────────────────────────────────┘ │ │ │ │ │ ▼ │ │ ┌────────────────────────────────────────────────────────────┐ │ │ │ Stage 4: 部署到SAE │ │ │ ├────────────────────────────────────────────────────────────┤ │ │ │ - SAE触发滚动部署 │ │ │ │ - 健康检查 -> 切换流量 │ │ │ │ - 自动回滚(如果失败) │ │ │ └────────────────────────────────────────────────────────────┘ │ └──────────────────────────────────────────────────────────────────┘ │ ▼ ┌──────────────────────────────────────────────────────────────────┐ │ 生产环境运行 │ │ - 健康检查监控 │ │ - 日志收集分析 │ │ - 性能指标监控 │ └──────────────────────────────────────────────────────────────────┘ ``` #### 3.2 初期手工部署流程(推荐) **阶段1:初期(1-2人团队,前3个月)** ```bash # ===== 前端部署 ===== cd frontend-v2 npm run build # 构建生产版本 docker build -t frontend:v1.0.0 . # 构建Docker镜像 docker tag frontend:v1.0.0 registry.cn-hangzhou.aliyuncs.com/your-namespace/frontend:v1.0.0 docker push registry.cn-hangzhou.aliyuncs.com/your-namespace/frontend:v1.0.0 # 在SAE控制台点击"部署" -> 选择新镜像 -> 确认 # ===== 后端部署 ===== cd backend npm run build # 编译TypeScript docker build -t backend:v1.0.0 . docker tag backend:v1.0.0 registry.cn-hangzhou.aliyuncs.com/your-namespace/backend:v1.0.0 docker push registry.cn-hangzhou.aliyuncs.com/your-namespace/backend:v1.0.0 # 在SAE控制台点击"部署" -> 选择新镜像 -> 确认 # ===== Python微服务部署 ===== cd extraction_service docker build -t python-service:v1.0.0 . docker tag python-service:v1.0.0 registry.cn-hangzhou.aliyuncs.com/your-namespace/python-service:v1.0.0 docker push registry.cn-hangzhou.aliyuncs.com/your-namespace/python-service:v1.0.0 # 在SAE控制台点击"部署" -> 选择新镜像 -> 确认 ``` **优势:** - ✅ 简单直接,学习成本低 - ✅ 完全可控,出错容易排查 - ✅ 无需配置CI/CD工具 **阶段2:成长期(3-10人团队,3个月后)** 配置GitHub Actions或阿里云云效自动化部署。 #### 3.3 部署频率建议 | 模块 | 部署频率 | 建议时间 | 回滚策略 | |------|---------|---------|---------| | **前端** | 每周1-2次 | 周五下午 | SAE一键回滚(保留3个版本) | | **Node.js后端** | 每周1-2次 | 周五下午 | SAE一键回滚 + 数据库回滚脚本 | | **Python微服务** | 每2周1次 | 周五下午 | SAE一键回滚 | | **Dify平台** | 按需(很少) | 周末 | Docker Compose重启旧镜像 | | **PostgreSQL** | 按需(迁移) | 周末凌晨 | RDS快照恢复 | ### 4. 开发到部署的检查清单 #### 4.1 代码准备 ``` ☐ 1. 本地测试通过 ├─ npm run dev / uvicorn正常运行 ├─ 核心功能手工测试 └─ 单元测试/集成测试通过(如果有) ☐ 2. 代码审查 ├─ Lint检查通过(eslint / flake8) ├─ 代码格式化(prettier / black) └─ 无敏感信息泄漏(.env文件不提交) ☐ 3. 环境变量确认 ├─ 所有生产环境变量已配置到SAE ├─ 数据库连接字符串正确(含connection_limit) └─ OSS/Dify等外部服务地址正确 ``` #### 4.2 Docker镜像构建 ``` ☐ 4. Dockerfile优化 ├─ 使用多阶段构建(减小镜像体积) ├─ 基础镜像版本固定(如 node:22-alpine,不用latest) ├─ 非root用户运行(安全) └─ 健康检查配置正确 ☐ 5. 镜像构建与测试 ├─ docker build成功 ├─ docker run本地测试通过 ├─ 镜像大小合理(前端<100MB,后端<300MB,Python<1GB) └─ 镜像打标签(版本号) ``` #### 4.3 部署到SAE ``` ☐ 6. 部署前准备 ├─ 备份数据库(RDS手动快照) ├─ 通知团队(如果是重大变更) └─ 准备回滚方案 ☐ 7. SAE部署 ├─ 推送镜像到ACR ├─ SAE选择新镜像版本 ├─ 滚动发布(灰度发布,逐个实例替换) └─ 观察日志和监控 ☐ 8. 部署后验证 ├─ 健康检查端点返回200 ├─ 核心功能冒烟测试 ├─ 日志无ERROR └─ 监控指标正常(CPU/内存/响应时间) ☐ 9. 回滚准备(如果失败) ├─ SAE一键回滚到上一版本 ├─ 数据库恢复快照(如果有Schema变更) └─ 排查问题日志 ``` --- ## Docker版本管理策略 ### 1. 镜像版本命名规范 #### 1.1 语义化版本 (Semantic Versioning) ``` 格式:{服务名}:{主版本}.{次版本}.{修订版本}[-{环境}] 示例: frontend:1.0.0 # 生产版本 frontend:1.0.0-dev # 开发版本 frontend:1.1.0 # 功能更新 frontend:1.1.1 # Bug修复 ``` **版本号规则:** - **主版本 (Major)**:重大架构变更,不兼容旧版本(如 1.x.x → 2.x.x) - **次版本 (Minor)**:新增功能,向下兼容(如 1.0.x → 1.1.x) - **修订版本 (Patch)**:Bug修复,完全兼容(如 1.0.0 → 1.0.1) #### 1.2 标签策略 | 标签类型 | 示例 | 用途 | 保留策略 | |---------|------|------|---------| | **版本号** | `v1.2.3` | 正式发布版本 | 永久保留 | | **latest** | `latest` | 最新稳定版 | 自动更新 | | **dev** | `dev` | 开发测试版 | 滚动保留最近10个 | | **Git SHA** | `sha-a1b2c3d` | 特定提交版本 | 按需保留 | | **日期** | `20251214` | 按日期归档 | 保留30天 | **完整示例:** ```bash # 构建时打多个标签 docker build -t frontend:v1.2.3 \ -t frontend:latest \ -t frontend:sha-a1b2c3d \ -t frontend:20251214 \ . # 推送到ACR docker tag frontend:v1.2.3 registry.cn-hangzhou.aliyuncs.com/aiclinical/frontend:v1.2.3 docker tag frontend:v1.2.3 registry.cn-hangzhou.aliyuncs.com/aiclinical/frontend:latest docker push registry.cn-hangzhou.aliyuncs.com/aiclinical/frontend:v1.2.3 docker push registry.cn-hangzhou.aliyuncs.com/aiclinical/frontend:latest ``` ### 2. 本地版本管理 #### 2.1 本地是否需要版本管理? **答案:初期不需要,成长期建议轻量管理。** | 阶段 | 本地管理策略 | 原因 | |------|-------------|------| | **初期(1-2人)** | ❌ 不需要 | - 开发者少,口头协调即可
- 本地镜像只用于测试
- 直接推送到ACR统一管理 | | **成长期(3-10人)** | ✅ 轻量管理 | - 使用Git标签管理版本
- `package.json`/`pyproject.toml`记录版本
- 本地镜像定期清理 | #### 2.2 本地镜像清理 ```bash # 查看本地镜像 docker images | grep frontend # 删除未使用的镜像(保留最近3个版本) docker image prune -a --filter "until=720h" # 删除30天前的镜像 # 删除所有未使用的镜像(危险,慎用) docker image prune -a ``` **建议清理频率:** - 开发机:每周清理一次 - CI/CD服务器:每次构建后自动清理 ### 3. ACR容器镜像仓库管理 #### 3.1 镜像仓库结构 ``` 阿里云容器镜像服务 (ACR) ├── 命名空间: aiclinical(团队共享) │ │ │ ├── 仓库: frontend │ │ ├── latest(自动更新) │ │ ├── v1.0.0 │ │ ├── v1.0.1 │ │ ├── v1.1.0 │ │ └── ... (保留最近20个版本) │ │ │ ├── 仓库: backend │ │ ├── latest │ │ ├── v1.0.0 │ │ ├── v1.0.1 │ │ └── ... │ │ │ ├── 仓库: python-service │ │ ├── latest │ │ ├── v1.0.0 │ │ └── ... │ │ │ └── 仓库: dify (可选,如果自定义构建) │ └── v0.6.13 │ └── 个人版免费配额:3个命名空间,无限仓库数,300GB存储/月 ``` #### 3.2 镜像生命周期管理 **保留策略:** ```yaml 规则1: 保留最新的20个版本标签 规则2: 保留所有带"v"前缀的正式版本(v1.0.0、v1.1.0等) 规则3: 自动清理30天前的dev/test标签 规则4: latest标签永久保留 ``` **ACR配置示例(控制台配置):** ``` 容器镜像服务 > 仓库管理 > frontend > 生命周期规则 ├─ 规则1: 保留最近20个版本 │ ├─ 类型: 按数量保留 │ ├─ 保留数量: 20 │ └─ 标签匹配: * │ └─ 规则2: 清理旧的dev标签 ├─ 类型: 按时间清理 ├─ 保留时间: 30天 └─ 标签匹配: *-dev ``` ### 4. 版本与Git的关系 #### 4.1 Git标签与Docker标签同步 ```bash # 开发流程 git add . git commit -m "feat: add user profile page" git push origin main # 发布版本时创建Git标签 git tag -a v1.2.3 -m "Release v1.2.3: Add user profile" git push origin v1.2.3 # 构建Docker镜像(版本号与Git标签一致) docker build -t frontend:v1.2.3 . docker tag frontend:v1.2.3 registry.cn-hangzhou.aliyuncs.com/aiclinical/frontend:v1.2.3 docker push registry.cn-hangzhou.aliyuncs.com/aiclinical/frontend:v1.2.3 ``` #### 4.2 自动版本号管理(可选) **方法1:从 `package.json` 读取版本号** ```json // frontend-v2/package.json { "name": "aiclinical-frontend", "version": "1.2.3", ... } ``` ```bash # 构建脚本自动读取版本号 VERSION=$(node -p "require('./package.json').version") docker build -t frontend:v$VERSION . ``` **方法2:从Git提交SHA生成版本号** ```bash # 使用Git SHA作为版本号(适合CI/CD) GIT_SHA=$(git rev-parse --short HEAD) docker build -t frontend:sha-$GIT_SHA . ``` ### 5. 版本管理工具推荐 | 工具 | 用途 | 适用阶段 | |------|------|---------| | **Git Tags** | 代码版本管理 | ✅ 所有阶段 | | **package.json/pyproject.toml** | 应用版本声明 | ✅ 所有阶段 | | **Docker Labels** | 镜像元数据标记 | ✅ 成长期+ | | **语义化版本工具 (semantic-release)** | 自动版本号生成 | 可选(成熟期) | | **Harbor/ACR版本管理** | 镜像仓库治理 | ✅ 成长期+ | --- ## 线上故障快速修复 ### 1. 故障分级与修复策略 | 故障等级 | 影响范围 | 修复策略 | 预期RTO | 示例 | |---------|---------|---------|---------|------| | **P0(致命)** | 全站不可用 | 立即回滚 | <5分钟 | 数据库连接失败、应用启动失败 | | **P1(严重)** | 核心功能不可用 | 回滚或热修复 | <30分钟 | 用户无法登录、文件上传失败 | | **P2(一般)** | 部分功能异常 | 热修复或下个版本 | <2小时 | 某个页面报错、样式错乱 | | **P3(轻微)** | 用户体验问题 | 下个版本修复 | <1天 | 文案错误、图标缺失 | ### 2. 修复方案对比 | 修复方法 | 适用场景 | 操作步骤 | 优点 | 缺点 | 推荐度 | |---------|---------|---------|------|------|--------| | **方案1:SAE一键回滚** | P0/P1故障 | SAE控制台点击"回滚" | ✅ 最快(<5分钟)
✅ 零风险 | ❌ 回到旧版本,新功能丢失 | ⭐⭐⭐⭐⭐ | | **方案2:热修复(重新部署完整镜像)** | P1/P2故障 | 修改代码→构建镜像→推送→部署 | ✅ 彻底修复
✅ 保留新功能 | ❌ 慢(10-30分钟)
❌ 需要完整构建 | ⭐⭐⭐⭐ | | **方案3:单文件热更新(不推荐)** | ❌ 不推荐 | SSH进容器→修改文件 | ✅ 快 | ❌ 容器重启后丢失
❌ 无版本记录
❌ 违反Docker理念 | ⭐ | | **方案4:配置热更新** | 配置错误 | SAE环境变量→重启应用 | ✅ 快(<5分钟)
✅ 无需重新构建 | ❌ 只适用于配置问题 | ⭐⭐⭐⭐ | ### 3. 详细修复流程 #### 3.1 方案1:SAE一键回滚(推荐)⭐⭐⭐⭐⭐ **适用场景:** - 新版本部署后发现严重Bug - 性能急剧下降 - 功能完全不可用 **操作步骤:** ``` 步骤1: 登录阿里云控制台 → SAE 步骤2: 选择问题应用(如 aiclinical-backend) 步骤3: 点击"部署历史" 步骤4: 找到上一个稳定版本(如 v1.2.2) 步骤5: 点击"回滚"按钮 步骤6: 确认 → SAE自动执行滚动回滚 步骤7: 观察健康检查和日志 步骤8: 验证功能恢复 预计时间:3-5分钟 ``` **SAE回滚机制:** ``` 回滚过程(滚动回滚,零停机) ├── 阶段1: 从ACR拉取旧版本镜像 ├── 阶段2: 启动1个旧版本实例 ├── 阶段3: 健康检查通过后,切换流量到旧实例 ├── 阶段4: 逐步停止新版本实例 ├── 阶段5: 全部实例回滚完成 └── 时间:2-3分钟(2实例的情况) ``` **回滚后的处理:** ``` ☐ 1. 验证核心功能恢复 ☐ 2. 通知团队回滚完成 ☐ 3. 分析故障原因(日志/监控) ☐ 4. 修复Bug(本地测试充分) ☐ 5. 重新部署修复版本 ``` #### 3.2 方案2:热修复(重新部署完整Docker镜像)⭐⭐⭐⭐ **适用场景:** - 无法回滚(旧版本也有问题) - Bug已定位且修复简单 - 需要保留新功能 **操作步骤:** ```bash # ===== 场景:后端API返回500错误 ===== # 步骤1: 本地复现问题 npm run dev # 测试API: POST /api/v1/users # 错误日志: TypeError: Cannot read property 'email' of undefined # 步骤2: 修复代码 # backend/src/modules/users/userService.ts # 修复:添加空值校验 if (!userData || !userData.email) { throw new Error('Email is required') } # 步骤3: 本地测试通过 npm run dev # 重新测试API → 200 OK # 步骤4: 构建新镜像(版本号升级) npm run build docker build -t backend:v1.2.4 . # 修订版本号+1 # 步骤5: 推送到ACR docker tag backend:v1.2.4 registry.cn-hangzhou.aliyuncs.com/aiclinical/backend:v1.2.4 docker push registry.cn-hangzhou.aliyuncs.com/aiclinical/backend:v1.2.4 # 步骤6: SAE部署 # 控制台 → 部署 → 镜像版本: v1.2.4 → 确认 → 滚动发布 # 步骤7: 观察部署过程 # SAE日志实时查看 → 无ERROR → 健康检查通过 # 步骤8: 验证修复 curl -X POST https://api.your-domain.com/api/v1/users \ -H "Content-Type: application/json" \ -d '{"email":"test@example.com"}' # 返回: 200 OK # 步骤9: 更新Git git add . git commit -m "hotfix: add email validation in userService" git tag v1.2.4 git push origin main git push origin v1.2.4 ``` **预计时间:10-30分钟** ``` 代码修复: 5分钟 构建镜像: 3-5分钟(Node.js后端) 推送镜像: 1-2分钟 SAE部署: 2-3分钟 验证: 2分钟 Git提交: 1分钟 ``` #### 3.3 方案3:单文件热更新(❌不推荐,仅紧急情况) **为什么不推荐?** 1. ❌ **容器重启后丢失**:容器是无状态的,重启后修改消失 2. ❌ **无版本记录**:无法追溯修改历史 3. ❌ **多实例不一致**:SAE有多个实例,只修改一个实例无效 4. ❌ **违反Docker理念**:容器应该是不可变的 **如果必须使用(极端紧急情况):** ```bash # ⚠️ 仅供紧急情况参考,不推荐 # 步骤1: 登录SAE实例(通过云助手) # SAE控制台 → 实例列表 → 登录实例 # 步骤2: 找到文件位置 cd /app ls -la # 步骤3: 修改文件 vi src/modules/users/userService.js # 修改错误的代码 # 步骤4: 重启应用(SAE会自动重启) # ⚠️ 注意:这个修改只在当前实例生效,重启后丢失 # 步骤5: 立即准备正式修复(方案2) # 本地修改 → 构建镜像 → 部署 ``` **总结:除非系统完全崩溃且无法回滚,否则不要使用单文件热更新!** #### 3.4 方案4:配置热更新(环境变量)⭐⭐⭐⭐ **适用场景:** - 数据库连接字符串错误 - API密钥/Token过期 - 外部服务地址变更 - Feature Flag开关 **操作步骤:** ``` # 场景:Dify API地址配置错误 步骤1: SAE控制台 → 选择应用 → 环境变量 步骤2: 找到错误的变量 DIFY_API_URL=http://172.16.1.100/v1 # ❌ 错误IP 步骤3: 修改为正确值 DIFY_API_URL=http://172.16.2.50/v1 # ✅ 正确IP 步骤4: 保存 → SAE提示"需要重启应用" 步骤5: 点击"重启应用" → 滚动重启(零停机) 步骤6: 观察日志 → 连接成功 步骤7: 验证功能恢复 预计时间:3-5分钟 ``` **环境变量修改的注意事项:** - ✅ 修改后必须重启应用才能生效 - ✅ 滚动重启,不影响服务可用性 - ⚠️ 敏感信息(密码)修改后,记得更新本地 `.env.example` - ⚠️ 如果涉及数据库迁移,确保数据库已准备好 ### 4. 故障预防与监控 #### 4.1 预防措施 ``` ☐ 1. 充分的本地测试 ├─ 核心功能手工测试 ├─ 边界条件测试 └─ 与生产环境类似的数据测试 ☐ 2. 灰度发布(SAE支持) ├─ 先部署到1个实例(10%流量) ├─ 观察10-30分钟 └─ 无问题后全量发布 ☐ 3. 健康检查完善 ├─ /health 端点检查数据库连接 ├─ /health 端点检查外部服务(Dify/OSS) └─ 健康检查失败自动重启 ☐ 4. 监控告警 ├─ 错误日志告警(SLS) ├─ API响应时间告警(ARMS) └─ 数据库连接数告警(RDS监控) ☐ 5. 自动化测试(未来) ├─ 单元测试(Jest / Pytest) ├─ 集成测试(Supertest / Playwright) └─ CI/CD中自动执行 ``` #### 4.2 监控指标 | 指标类型 | 监控指标 | 告警阈值 | 处理措施 | |---------|---------|---------|---------| | **应用监控** | 错误率 | >5% | 立即查看日志,考虑回滚 | | **应用监控** | API响应时间 | >2秒 | 检查数据库慢查询、外部服务 | | **应用监控** | 健康检查失败 | >3次 | 自动重启实例,检查依赖服务 | | **数据库监控** | 连接数 | >80% | 检查连接泄漏,增加连接池 | | **数据库监控** | 慢查询 | >1秒 | 优化SQL,添加索引 | | **容器监控** | CPU使用率 | >70% | 检查死循环,考虑扩容 | | **容器监控** | 内存使用率 | >80% | 检查内存泄漏,重启实例 | ### 5. 故障修复决策树 ``` ┌─────────────────┐ │ 发现线上故障 │ └────────┬────────┘ │ ┌────────▼────────┐ │ 影响范围评估? │ └────┬────────────┘ │ ┌──────────┼──────────┐ │ │ ┌───────▼────────┐ ┌──────▼────────┐ │ 全站不可用 │ │ 部分功能异常 │ │ (P0/P1) │ │ (P2/P3) │ └───────┬────────┘ └──────┬────────┘ │ │ ┌───────▼────────┐ ┌──────▼────────┐ │ 能否快速定位? │ │ 能否快速修复? │ └───┬────────┬───┘ └──┬────────┬───┘ │ No │ Yes │ Yes │ No │ │ │ │ ┌─────▼──┐ ┌──▼─────┐ ┌──▼──┐ ┌───▼────┐ │ 立即 │ │ 是配置 │ │ 热修│ │ 下个版 │ │ 回滚 │ │ 问题? │ │ 复 │ │ 本修复 │ └────────┘ └──┬──┬──┘ └─────┘ └────────┘ │ │ ┌─────▼──▼────┐ │ 修改环境变量 │ │ + 重启应用 │ └──────────────┘ ``` --- ## 部署文档导航 ### 📚 独立部署文档清单 | # | 文档名称 | 部署对象 | 目标环境 | 预计时间 | |---|---------|---------|---------|---------| | 1 | [PostgreSQL部署策略-摸底报告](./PostgreSQL部署策略-摸底报告.md) | PostgreSQL 15数据库 | RDS PostgreSQL 15 | 10分钟(pg_dump导入) | | 2 | [Dify-ECS部署完全指南](./03-Dify-ECS部署完全指南.md) | Dify RAG平台 | ECS + Docker Compose | 30-60分钟 | | 3 | [Python微服务-SAE容器部署指南](./04-Python微服务-SAE容器部署指南.md) | Python微服务 | SAE容器实例 | 20-30分钟 | | 4 | [Node.js后端-SAE容器部署指南](./05-Node.js后端-SAE容器部署指南.md) | Node.js后端 | SAE容器实例 | 20-30分钟 | | 5 | [前端Nginx-SAE容器部署指南](./06-前端Nginx-SAE容器部署指南.md) | React前端 | SAE容器实例 | 15-20分钟 | **总部署时间:** 约2-3小时(从0到全部上线) ### 🎯 部署顺序建议 ``` 第一阶段:基础设施(Day 1)⭐ 必需 ├── 1. 创建VPC和安全组 (10分钟) ├── 2. ⭐ 创建NAT网关 + 绑定EIP (15分钟) ← 新增,必需! ├── 3. 部署RDS PostgreSQL 15 (10分钟,等待实例创建15分钟) ├── 4. 导入数据库(pg_dump) (5分钟) └── 5. 创建OSS Bucket (5分钟) └── 配置生命周期、权限 第二阶段:核心服务(Day 1)⚠️ 临时配置 ├── 6. 部署Node.js后端到SAE (20分钟) │ └── ⚠️ DIFY_API_KEY=temp(临时值,等Dify部署后更新) ├── 7. 部署Python微服务到SAE (20分钟) └── 8. 端到端测试(后端API + Python服务) (15分钟) 第三阶段:用户界面(Day 2) ├── 9. 部署前端到SAE (15分钟) └── 10. 完整功能测试(不含PKB模块) (30分钟) 第四阶段:Dify服务(Day 2-3)⭐ PKB模块必需 ├── 11. 部署Dify到ECS (60分钟) ├── 12. 登录Dify生成API Key (5分钟) ├── 13. 更新后端DIFY_API_KEY环境变量 (5分钟) └── 14. 测试PKB知识库功能 (15分钟) 总计:约4-5小时(实际操作时间,不含等待) ``` ### 📖 如何使用这些文档? #### 新团队首次部署 ``` 步骤1: 阅读本《部署架构总览》 ├─ 理解整体架构 ├─ 理解模块依赖关系 └─ 熟悉阿里云服务 步骤2: 按顺序阅读独立部署文档 ├─ PostgreSQL部署策略(理解数据库架构) ├─ Node.js后端部署(核心服务) ├─ Python微服务部署(能力支撑) ├─ 前端Nginx部署(用户界面) └─ Dify部署(可选,PKB模块需要) 步骤3: 准备阿里云账号和资源 ├─ 实名认证 ├─ 充值(建议¥500起步) ├─ 创建RAM子账号(安全) └─ 开通SAE/RDS/OSS/ACR服务 步骤4: 按第一阶段→第二阶段→第三阶段顺序部署 └─ 每个阶段完成后测试验证 步骤5: 监控与优化 ├─ 配置告警规则 ├─ 观察7天运行情况 └─ 根据实际情况调整规格 ``` #### 已有系统维护 ``` 日常开发部署: ├─ 修改代码 ├─ 本地测试 ├─ 构建Docker镜像 ├─ 推送到ACR └─ SAE控制台部署 线上故障处理: ├─ 参考"线上故障快速修复"章节 ├─ P0/P1: 立即回滚 ├─ P2/P3: 热修复或下个版本 └─ 故障复盘,更新文档 新模块上线: ├─ 参考对应的独立部署文档 ├─ 确认依赖服务(数据库/OSS/其他服务) ├─ 灰度发布(先1个实例) └─ 全量发布 ``` ### 🔗 文档间的引用关系 ``` 00-部署架构总览.md (本文档) │ ├──► PostgreSQL部署策略-摸底报告.md │ ├─ 数据库架构详解 │ ├─ pg_dump导入流程 │ ├─ 备份策略 │ └─ 最佳实践 │ ├──► 03-Dify-ECS部署完全指南.md │ ├─ Docker Compose配置 │ ├─ Nginx路由层 │ ├─ Swap配置 │ └─ 故障排查 │ ├──► 04-Python微服务-SAE容器部署指南.md │ ├─ Dockerfile多阶段构建 │ ├─ 系统依赖安装(PyTorch/OpenCV) │ ├─ SAE配置 │ └─ 内网调用 │ ├──► 05-Node.js后端-SAE容器部署指南.md │ ├─ Prisma反向同步(db pull) │ ├─ 数据库连接池 │ ├─ 优雅关闭 │ └─ 环境变量配置 │ └──► 06-前端Nginx-SAE容器部署指南.md ├─ SPA路由配置 ├─ API反向代理 ├─ 静态资源缓存 └─ envsubst动态配置 ``` --- ## 🛡️ 安全与最佳实践 ### 1. 时区统一配置 ⭐⭐⭐⭐⭐ **问题:** 不同服务的时区不一致会导致: - 日志时间对不上(前端14:00,后端06:00) - pg-boss定时任务在错误时间触发 - 用户看到的时间戳错误 **解决:** 所有服务统一使用 `Asia/Shanghai` 时区 ```dockerfile # backend/Dockerfile - Node.js后端 FROM node:22-alpine AS runtime RUN apk add --no-cache tzdata ENV TZ=Asia/Shanghai # ... 其他配置 # extraction_service/Dockerfile - Python微服务 FROM python:3.11-slim AS runtime RUN apt-get update && apt-get install -y tzdata ENV TZ=Asia/Shanghai RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone # ... 其他配置 # frontend-v2/Dockerfile - 前端(已配置) FROM nginx:1.25-alpine RUN apk add --no-cache tzdata ENV TZ=Asia/Shanghai # ... 其他配置 ``` ```sql -- RDS PostgreSQL 时区配置 -- RDS控制台 > 参数设置 > timezone timezone = Asia/Shanghai ``` **验证时区:** ```bash # 查看容器时区 docker exec date # 应该显示:Sat Dec 14 14:30:00 CST 2024 # 查看RDS时区 psql -c "SHOW timezone;" # 应该显示:Asia/Shanghai ``` ### 2. 安全组配置最佳实践 ⭐⭐⭐⭐⭐ #### ECS安全组配置(Dify服务器) **正确配置:** ```bash # ECS控制台 > 安全组 > 配置规则 # ✅ 入方向规则(Inbound) 允许 80/TCP 来源:172.16.0.0/12 # Nginx(VPC内网访问) 允许 22/TCP 来源:您的办公室公网IP # SSH管理 拒绝 所有 来源:0.0.0.0/0 # 默认拒绝 ``` **⚠️ 安全红线(绝对禁止):** ```bash # ❌ 禁止 5000/TCP(Dify API)对公网开放 # 后果:黑客可绕过后端消耗LLM额度 # ❌ 禁止 8080/TCP(Weaviate)对公网开放 # 后果:向量数据可能被窃取 # ❌ 禁止 6379/TCP(Redis)对公网开放 # 后果:Redis无密码,可能被清空 # ✅ 正确:docker-compose.yaml中端口绑定 services: redis: ports: - "127.0.0.1:6379:6379" # 只监听本地 weaviate: ports: - "127.0.0.1:8080:8080" # 只监听本地 ``` **验证安全配置:** ```bash # 从公网测试(应该失败) telnet ECS公网IP 6379 # 应该超时或拒绝连接 # 从VPC内测试(应该成功) curl http://172.16.x.x # Dify内网地址 # 应该返回 Dify 响应 ``` 🔗 **详细配置:** 参考 `03-Dify-ECS部署完全指南.md` ### 3. 镜像拉取策略 ⭐⭐⭐⭐⭐ **问题:** SAE可能不会拉取新镜像(代码不更新的"灵异事件") ```bash # 场景: 开发者修改代码 → 构建镜像 → 推送到ACR(覆盖v1.0.0) → SAE部署 → 发现代码没更新??? # 原因: SAE默认镜像拉取策略可能是 IfNotPresent 如果本地已有 v1.0.0,不会重新拉取 ``` **解决方案:** | 方案 | 适用环境 | 优势 | 劣势 | |------|---------|------|------| | **方案A:版本号管理** | 生产环境 | 版本可追溯,稳定 | 需手动递增版本号 | | **方案B:Always拉取** | 测试环境 | 始终最新,方便 | 每次重启拉取,慢 | **方案A:每次部署使用新版本号(强烈推荐)** ```bash # 使用语义化版本号 v1.0.0 → v1.0.1 → v1.0.2 ... # 或使用时间戳 v20251214-1430 → v20251214-1530 ... # 或使用Git SHA v-a1b2c3d → v-b2c3d4e ... ``` **方案B:配置SAE镜像拉取策略** ```bash # SAE控制台 > 应用配置 > 镜像设置 镜像拉取策略:Always # ⚠️ 注意: # - 每次重启都会拉取镜像(启动稍慢) # - 适合测试环境,不推荐生产环境 ``` ### 4. 开发调试最佳实践 #### 本地连接RDS数据库(SSH隧道) **场景:** 开发人员需要用Navicat/DBeaver查看RDS数据 **问题:** RDS在VPC内网,本地无法直接访问 **解决:** 通过ECS建立SSH隧道 ```bash # 步骤1:建立SSH隧道 ssh -N -L 5433:rm-xxxxx.pg.rds.aliyuncs.com:5432 \ root@ECS公网IP \ -i ~/.ssh/dify-ecs.pem # 参数说明: # -N: 不执行远程命令,只建立隧道 # -L: 本地端口转发 # 5433: 本地监听端口(避免与本地PostgreSQL 5432冲突) # rm-xxxxx: RDS内网地址 # 5432: RDS端口 # 步骤2:Navicat/DBeaver连接配置 主机:localhost 端口:5433 用户名:aiclinical_rw 密码:(RDS密码) 数据库:ai_clinical_research # 步骤3:测试连接 # 应该成功连接到RDS! ``` **后台运行(可选):** ```bash # 方法1:nohup后台运行 nohup ssh -N -L 5433:rm-xxxxx.pg.rds.aliyuncs.com:5432 \ root@ECS-IP -i key.pem > /dev/null 2>&1 & # 方法2:保持隧道运行(新终端窗口) ssh -N -L 5433:rm-xxxxx.pg.rds.aliyuncs.com:5432 \ root@ECS-IP -i key.pem # 保持此终端窗口打开 ``` 🔗 **详细步骤参考:** `07-关键配置补充说明.md` 第7节 ### 5. Python服务内存管理 ⭐⭐⭐⭐ **问题:** Python服务(PyMuPDF/Nougat)内存密集,容易OOM | 场景 | CPU | 内存 | Workers | 适用情况 | |------|-----|------|---------|---------| | **基础版** | 1核 | 2GB | 2 | 简单PDF解析 | | **标准版** | 2核 | 4GB | 3 | 包含OCR(Nougat) | | **增强版** | 2核 | 8GB | 4 | 大量OCR + 高并发 | **⚠️ 重要提示:** - 如果遇到OOM(Out of Memory),优先升级内存至4GB - 或者限制Gunicorn并发数:`--workers 1 --threads 2` - PyMuPDF + Nougat OCR单个请求可能占用500MB-1GB内存 **Dockerfile优化(已应用):** ```dockerfile CMD ["gunicorn", "main:app", \ "--bind", "0.0.0.0:8000", \ "--workers", "2", \ "--timeout", "120", \ "--max-requests", "100", \ "--max-requests-jitter", "10"] ``` 🔗 **详细配置:** 参考 `04-Python微服务-SAE容器部署指南.md` ### 6. NAT网关成本优化 **当前方案:NAT网关(推荐)** ``` 成本:NAT网关¥60/月 + EIP流量费¥30-50/月 = ¥90-110/月 优势:稳定可靠,生产环境标配 劣势:成本相对较高 ``` **替代方案(不推荐,仅供参考):** | 方案 | 成本 | 稳定性 | 复杂度 | 推荐度 | |------|------|--------|--------|--------| | NAT网关 | ¥100/月 | ⭐⭐⭐⭐⭐ | 低 | ⭐⭐⭐⭐⭐(推荐)| | SAE绑定EIP | ¥30-50/月 | ⭐⭐⭐ | 中 | ⭐⭐⭐(部分地域)| | ECS做SNAT | ¥0(复用ECS) | ⭐⭐ | 高 | ⭐⭐(不推荐)| **建议:** 初创团队不要在这里省钱,NAT网关是生产环境的标配。 --- ## 📝 总结与建议 ### 核心架构特点 1. **✅ 云原生Serverless架构** - 前端/后端/Python全部容器化部署到SAE - 弹性伸缩,按需付费 - 零运维,自动故障转移 2. **✅ 微服务隔离** - 5个核心模块职责清晰 - 内网通信,免流量费 - 独立部署,互不影响 3. **✅ 数据安全可控** - PostgreSQL 10个Schema隔离 - RDS自动备份 + PITR - VPC内网隔离,白名单控制 4. **✅ 适合初创团队** - 1-2人可运维 - 手工部署简单直接 - 成本可控(¥1,100/月起) ### 下一步行动 ``` ☐ 第1周:基础设施搭建 ├─ 阿里云账号准备 ├─ VPC/RDS/OSS创建 └─ 数据库导入 ☐ 第2周:核心服务部署 ├─ Node.js后端上线 ├─ Python微服务上线 ├─ 前端上线 └─ 端到端测试 ☐ 第3周:可选服务 + 监控 ├─ Dify部署(如需PKB模块) ├─ 配置监控告警 └─ 压力测试 ☐ 第4周:稳定性优化 ├─ 根据监控数据调整资源 ├─ 故障演练(回滚、修复) └─ 文档完善 ``` ### 持续改进建议 | 阶段 | 改进方向 | 优先级 | |------|---------|--------| | **3个月内** | - 完善监控告警
- 编写运维手册
- 故障演练 | ⭐⭐⭐⭐⭐ | | **6个月内** | - 配置CI/CD
- 自动化测试
- 性能优化 | ⭐⭐⭐⭐ | | **1年内** | - 跨地域灾备
- 容器编排升级(ACK)
- 微服务治理 | ⭐⭐⭐ | --- **文档创建人:** AI助手 **最后更新:** 2025-12-14 **版本:** v1.0 **核心理念:架构清晰、职责分离、云原生、易于运维** ⭐⭐⭐