Files
wecom_it_smart_desk/docs/正式环境独立部署架构方案.md
T

411 lines
20 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.
# 智能IT助手 — 正式环境独立部署架构方案
> **版本**: v1.1 | **日期**: 2026-06-03 | **编制**: 宋献(IT支持组组长)
> **目标**: 以对现有正式环境影响最小、责任边界最清晰的方式,完成新系统正式环境部署
---
## 一、核心决策原则
基于以下四个约束条件,确立本次架构设计的决策原则:
| # | 约束 | 推导原则 |
|---|------|---------|
| 1 | 对现有正式环境架构影响最小 | **物理隔离 > 逻辑隔离**:能用独立资源就不用共享资源 |
| 2 | 避免后续上线/变更影响现有服务 | **独立Nginx入口**:变更新系统反代规则时不影响旧系统 |
| 3 | 减少服务影响和依赖 | **最小化外部依赖**:只依赖真正不可替代的外部服务 |
| 4 | 避免混搭导致责任不清 | **独立数据库 + 独立Redis**:不共享存储层,运维边界清晰 |
> **一句话总结**:新系统作为**独立服务单元**部署,与现有智能IT数据平台(Django)在物理资源层面完全解耦,仅通过 HTTP API 调用共享 AI 能力(Dify/RAGFlow/Qwen)。
---
## 二、与复用评估的关键修正
原复用评估(团队沟通文档第7章)建议了部分资源共享方案。基于上述独立部署原则,修正如下:
| 原复用建议 | 修正方案 | 理由 |
|-----------|---------|------|
| 同机部署于 10.80.0.86 | **申请独立服务器/VM** | 避免端口冲突、资源争抢、变更互相影响 |
| Redis 复用同实例(db=0/db=1 | **独立 Redis 容器** | db 号隔离不彻底(FLUSHDB 误操作、内存OOM互相影响) |
| 使用旧系统 Nginx | **独立 Nginx 容器** | 变更新系统反代配置时不影响旧系统路由 |
| 复用旧系统 PostgreSQL 实例 | **独立 PostgreSQL 容器** | 数据库是"责任边界"的核心——谁的数据谁负责 |
| SSL 复用现有证书 | **可复用**(Nginx 层读取同一证书文件) | 证书是静态文件,只读访问无耦合风险 |
**仍然保持的复用(零耦合):**
| 资源 | 复用方式 | 耦合度 |
|------|---------|--------|
| 企微自建应用凭证 | 配置文件引用(同一个 CorpID/AgentID/Secret | 零耦合(只读凭证) |
| Dify Workflow API | HTTP 调用 `yw-dify.dc.servyou-it.com` | 外部依赖(HTTP |
| RAGFlow 知识库 | HTTP 调用 `10.80.0.85:8080` | 外部依赖(HTTP |
| Qwen3-30B 大模型 | HTTP 调用 `10.80.0.49:5000` | 外部依赖(HTTP |
| SSL 证书文件 | Nginx 挂载只读 | 零耦合(静态文件) |
---
## 三、资源申请清单
### 3.1 服务器
| 项目 | 申请内容 | 说明 |
|------|---------|------|
| 服务器数量 | **1 台 VM** | Docker Compose 单机部署,4 个容器运行在同一 Docker Engine |
| 最低配置 | 4C8G + 100GB SSD | 预留 2 年增长空间 |
| 推荐配置 | 8C16G + 200GB SSD | 考虑到 M2 阶段接入 AI 后的并发请求量 |
| 操作系统 | CentOS 7.9+ / Rocky Linux 8+ / Ubuntu 22.04 LTS | 公司标准镜像 |
| 网络域 | **OA 服务器网络** | 与现有 10.80.0.86 同域,办公网默认可达 |
| Docker | 预装 Docker Engine 24+ + Docker Compose v2 | 基础运行环境 |
**为什么不在旧服务器上部署?**
```
10.80.0.86(现状):
├── Django 3.2(智能IT数据平台)—— 生产运行中
├── PostgreSQL 13(本地实例) —— 生产运行中
└── Redis 7 —— 生产运行中
│ ❌ 不推荐:新系统 FastAPI 同机部署
│ 风险1: 端口冲突(旧Django :8000, 新FastAPI也需要 :8000
│ 风险2: 内存竞争(Python进程内存开销大)
│ 风险3: Docker 服务重启影响两个系统
│ 风险4: 变更新系统 Nginx 配置时可能影响旧系统
新服务器(建议):
├── Docker Engine
│ ├── wecom_it_nginx —— 独立 Nginx 容器
│ ├── wecom_it_backend —— FastAPI 后端
│ ├── wecom_it_postgres —— PostgreSQL 16
│ └── wecom_it_redis —— Redis 7
└── 完全不接触旧系统资源
```
### 3.2 域名
| 项目 | 申请内容 |
|------|---------|
| 域名 | `itdesk.dc.servyou-it.com`(建议) |
| 解析目标 | 新服务器 IP(OA 网络) |
| 用途 | Nginx 统一入口 + OAuth2 回调 + CORS |
> 备选域名:`itdesk-oa.servyou-it.com` 或沿用 `it-dataquery` 子域模式改为 `it-smartdesk`
### 3.3 防火墙/网络策略
| 方向 | 源 | 目标 | 端口 | 用途 |
|------|-----|------|------|------|
| 入站 | 办公网 | 新服务器 | 80/443 | 坐席浏览器访问工作台 |
| 入站 | 企微服务器 | 新服务器 | 443 | 企微消息回调 |
| 出站 | 新服务器 | `qyapi.weixin.qq.com` | 443 | 企微 API 调用 |
| 出站 | 新服务器 | `yw-dify.dc.servyou-it.com` | 443 | Dify AI 调用(M2 |
| 出站 | 新服务器 | `10.80.0.85` | 8080 | RAGFlowM2 |
| 出站 | 新服务器 | `10.80.0.49` | 5000 | Qwen3-30BM2 |
| 出站 | 新服务器 | NTP 服务器 | 123 | 时间同步 |
> **不需要开通**:新服务器 → 10.80.0.86(完全不需要访问旧系统)
---
## 四、架构设计
### 4.1 网络拓扑
```
┌────────────────────────────┐
│ 企微服务器(外部) │
│ qyapi.weixin.qq.com │
└──────────┬─────────────────┘
│ HTTPS :443
┌──────────────── 办公网络 ────────────────────────────────┐
│ │
│ ┌──────────┐ ┌──────────────────────────┐ │
│ │ 坐席浏览器 │────────▶│ https://itdesk.dc. │ │
│ │ (内网) │ HTTPS │ servyou-it.com │ │
│ └──────────┘ └──────────┬───────────────┘ │
│ │ │
├────────────────── OA 服务器网络 ──┼───────────────────────┤
│ │ │
│ ┌───────▼──────────────┐ │
│ │ 新服务器 (Docker) │ │
│ │ │ │
│ │ ┌────────────────┐ │ │
│ │ │ Nginx :80/443 │ │ │
│ │ │ 独立容器 │ │ │
│ │ └───────┬────────┘ │ │
│ │ │ │ │
│ │ ┌───────▼────────┐ │ │
│ │ │ FastAPI :8000 │ │ │
│ │ │ 独立容器 │ │ │
│ │ └───┬───────┬────┘ │ │
│ │ │ │ │ │
│ │ ┌───▼──┐ ┌──▼───┐ │ │
│ │ │ PG16 │ │Redis7│ │ │
│ │ │独立容器│ │独立容器│ │ │
│ │ └──────┘ └──────┘ │ │
│ └──────────────────────┘ │
│ │ │
│ ┌────────▼──────────────┐ │
│ │ 现有 AI 服务(外部依赖)│ │
│ │ ├─ Dify (M2阶段调用) │ │
│ │ ├─ RAGFlow (M2调用) │ │
│ │ └─ Qwen3-30B (M2调用) │ │
│ └───────────────────────┘ │
│ │
│ ┌─────────────────────────────────────────┐ │
│ │ 现有智能IT数据平台 (10.80.0.86) │ │
│ │ Django + PG13 + Redis │ │
│ │ ⚠️ 新系统不访问此服务器 │ │
│ └─────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────────┘
```
### 4.2 容器拓扑
```
新服务器 Docker Engine
├── Docker Network: itdesk_net (bridge, internal)
│ │
│ ├── Container: wecom_it_postgres
│ │ Image: postgres:16-alpine
│ │ Volume: wecom_it_postgres_data
│ │ Port: 5432 (仅 itdesk_net 内部)
│ │
│ ├── Container: wecom_it_redis
│ │ Image: redis:7-alpine
│ │ Volume: wecom_it_redis_data
│ │ Port: 6379 (仅 itdesk_net 内部)
│ │
│ ├── Container: wecom_it_backend
│ │ Image: wecom-it-desk-backend:latest
│ │ Port: 8000 (仅 itdesk_net 内部)
│ │ Env: DATABASE_URL, REDIS_URL, WECOM_*
│ │ Healthcheck: GET /health
│ │
│ └── Container: wecom_it_nginx
│ Image: nginx:1.27-alpine
│ Port: 80:80, 443:443 (宿主机映射)
│ Volumes: nginx.conf:ro, 前端dist:ro, SSL:ro
│ Healthcheck: GET /health
└── Volumes (命名卷,持久化)
├── wecom_it_postgres_data
└── wecom_it_redis_data
```
### 4.3 关键隔离策略
| 隔离层面 | 方案 | 隔离效果 |
|---------|------|---------|
| **服务器级** | 独立 VM,不共用宿主机 | 挂了不影响旧系统 |
| **网络级** | Docker 内部网络 `itdesk_net`,PG/Redis 不暴露宿主机端口 | 外部无法直连数据库 |
| **存储级** | 独立命名卷,不共用 Volume | 数据完全隔离 |
| **域名级** | 独立子域名 + 独立 Nginx 容器 | 变更反代规则不影响旧系统 |
| **认证级** | JWT + 独立 Redis,不依赖旧系统 Session | 账户体系独立 |
| **依赖级** | 仅 HTTP 调用外部 AI 服务 | 外部服务故障只影响 M2 功能 |
---
## 五、与现有系统的交互边界
### 5.1 M1 阶段(当前)— 零交互
```
新系统 现有系统
┌─────────────┐ ┌─────────────────┐
│ 企微回调接收 │ │ 智能IT数据平台 │
│ 坐席工作台 │ ← 无交互 → │ (Django) │
│ 员工H5端 │ │ 数据查询/标注 │
│ PG16+Redis7 │ │ PG13+Redis │
└─────────────┘ └─────────────────┘
```
M1 阶段新系统和现有系统**完全无交互**,各自独立运行。
### 5.2 M2 阶段 — HTTP 只读调用
```
新系统 现有系统
┌─────────────┐ HTTP(只读) ┌─────────────────┐
│ FastAPI │─────┬──────────▶│ Dify Workflow │
│ │ │ │ (AI 回复) │
│ │ ├──────────▶│ RAGFlow │
│ │ │ │ (知识库检索) │
│ │ └──────────▶│ Qwen3-30B │
│ │ │ (大模型) │
│ │ HTTP(只读) │ │
│ │────────────────▶│ Dify DB (只读) │
│ │ 历史对话同步 │ 10.80.128.40 │
└─────────────┘ └─────────────────┘
```
M2 阶段新增的对接全部是 **HTTP 只读调用**,新系统不写任何数据到现有系统数据库。
### 5.3 M3 阶段 — 可选数据合并
```
M3 阶段(远期):
├── 数据平台 → 可保留独立运行(零影响方案)
├── 或 → 新系统接管统计报表功能(需迁移历史数据)
└── 决策点:届时根据 M1/M2 运行效果评估
```
---
## 六、部署流程
### 6.1 部署前准备清单
| # | 事项 | 责任人 | 预计耗时 |
|---|------|--------|---------|
| 1 | 申请 OA 网络服务器 VM | 宋献 → 运维 | 1-3 天 |
| 2 | 申请域名 `itdesk.dc.servyou-it.com` | 宋献 → 运维 | 0.5 天 |
| 3 | 申请防火墙策略(见 §3.3) | 宋献 → 网络组 | 1-2 天 |
| 4 | 确认企微自建应用回调 URL | 宋献 | 即时 |
| 5 | 准备 SSL 证书(复用或新申请) | 宋献 → 运维 | 即时/1天 |
| 6 | 服务器安装 Docker + Compose | 运维/宋献 | 0.5 天 |
### 6.2 部署步骤
```
Step 1: 服务器就绪
├── SSH 登录新服务器
├── 确认 Docker Engine 版本 ≥ 24
├── 确认 Docker Compose v2 可用
└── 创建部署目录 /opt/wecom-it-desk/
Step 2: 代码部署
├── git clone 或 scp 项目到 /opt/wecom-it-desk/
├── cp .env.production .env
├── 编辑 .env 填入真实企微凭证
└── bash scripts/build.sh # 构建前端
Step 3: 启动服务
├── docker compose up -d
├── 等待 healthcheck 全部通过
├── docker compose ps # 确认 4 容器 running
└── curl http://localhost:8000/health # 确认 API 可用
Step 4: Nginx + HTTPS
├── 挂载 SSL 证书到 ./nginx/ssl/
├── 启用 nginx.conf 中 HTTPS 段
├── docker compose restart nginx
└── curl https://itdesk.dc.servyou-it.com/health
Step 5: 企微回调验证
├── 企微管理后台 → 自建应用 → 接收消息
├── URL: https://itdesk.dc.servyou-it.com/api/wecom/callback
├── Token + EncodingAESKey(与 .env 一致)
└── 点击「验证」→ 确认通过
Step 6: 冒烟测试
├── 员工企微发送消息 → 后端日志确认收到
├── 坐席登录工作台 → 看到新会话
├── 坐席回复 → 员工企微收到消息
└── 全部通过 → 上线完成
```
### 6.3 回滚方案
```
回滚命令(一条命令恢复):
docker compose down # 停止新系统所有容器
# 旧系统不受任何影响(独立服务器,无共享资源)
问题定位期间:
docker compose logs -f backend # 查看后端日志
docker compose ps # 查看容器状态
```
---
## 七、运维边界与责任划分
### 7.1 责任矩阵
| 运维操作 | 新系统 | 旧系统 | 影响范围 |
|---------|--------|--------|---------|
| 重启 PostgreSQL | 仅影响新系统 | 不受影响 | 独立实例 |
| 重启 Redis | 仅影响新系统 | 不受影响 | 独立实例 |
| 修改 Nginx 配置 | 仅影响新系统路由 | 不受影响 | 独立容器 |
| 更新后端代码 | 仅影响新系统 | 不受影响 | 独立容器 |
| Docker 服务重启 | 仅影响新系统 | 不受影响 | 独立宿主机 |
| 企微应用配置变更 | **同时影响两个系统**(共用应用) | — | ⚠️ 唯一共享点 |
| Dify/RAGFlow/Qwen 故障 | 影响新系统 M2 功能 | 可能影响旧系统 | 外部依赖 |
> **唯一耦合点**:企微自建应用。变更应用配置(如 Secret 轮换、回调 URL 修改)需通知双方。
### 7.2 监控指标
```yaml
# 建议在新服务器上配置的基础监控
主机层面:
- CPU 使用率 < 80%
- 内存使用率 < 80%
- 磁盘使用率 < 70%
容器层面:
- docker compose ps 全部 "Up" 状态
- Nginx 健康检查: GET /health → 200
- Backend 健康检查: GET /health → 200
业务层面(后续接入):
- 企微消息回调成功率 > 99%
- API 响应时间 P95 < 500ms
```
### 7.3 备份策略
| 备份对象 | 方法 | 频率 | 保留 |
|---------|------|------|------|
| PostgreSQL 数据 | `pg_dump` + 卷快照 | 每日凌晨 | 7 天 |
| Redis 数据 | `SAVE` + 复制 dump.rdb | 每日凌晨 | 7 天 |
| Docker 卷 | `docker run --rm -v wecom_it_postgres_data:/data -v $(pwd):/backup alpine tar czf /backup/pg_backup.tar.gz -C /data .` | 每周 | 4 周 |
---
## 八、风险矩阵
| 风险 | 概率 | 影响 | 缓解措施 |
|------|------|------|---------|
| 新服务器申请被拒/延迟 | 中 | 部署延期 | 短期退化方案:使用旧服务器但严格端口分离+独立 compose |
| SSL 证书到期 | 低 | HTTPS 不可用 | 复用现有通配符证书(统一管理到期时间) |
| 企微应用配置变更导致双系统异常 | 低 | 双系统消息中断 | 建立变更通知机制,双方知晓 |
| Dify/RAGFlow 服务不可用 | 中 | M2 阶段 AI 功能不可用 | 降级:纯坐席模式仍可正常工作 |
| Docker 宿主机故障 | 低 | 新系统全宕 | Docker Compose 配置即代码,重建速度快 |
### 8.1 退化方案(如果申请不到新服务器)
```
短期退化方案(临时,不推荐长期使用):
旧服务器 10.80.0.86 上:
├── 端口映射: Nginx 新容器用 81/444(避免与旧 Nginx 冲突)
├── 独立 compose 项目: docker compose -p itdesk up -d
├── 独立 Docker 网络: itdesk_net(不与 dbquery_net 混用)
└── 资源限制: 限制 backend 容器内存上限(--memory=2g
从退化方案正式迁移到独立服务器时:
├── docker compose down
├── 复制卷数据到新服务器
├── 新服务器上 docker compose up -d
└── 修改域名解析 → 完成迁移
```
---
## 九、决策总结
| 决策项 | 选择 | 核心理由 |
|--------|------|---------|
| 部署服务器 | **独立 VM**(非 10.80.0.86) | 物理隔离 = 责任清晰 + 变更互不影响 |
| PostgreSQL | **独立容器**pg:16-alpine | 数据库是"责任边界"核心,绝不能共享 |
| Redis | **独立容器**redis:7-alpine | 避免误操作和 OOM 互相影响 |
| Nginx | **独立容器 + 独立子域名** | 变更反代规则不影响旧系统 |
| Docker 网络 | **独立 bridge 网络**itdesk_net | 不与 dbquery_net 互通 |
| 外部 AI 服务 | HTTP 只读调用 | 外部依赖合理复用,通过降级策略容错 |
| 企微应用凭证 | 配置文件复用 | 零耦合(只读凭证),唯一共享点 |
| SSL 证书 | 文件复用(只读挂载) | 静态文件,无耦合风险 |
> **一句话**:新系统是一个**独立的 Docker Compose 应用**,部署在**独立服务器**上,通过**独立域名**提供服务,与现有系统共享的只有企微应用凭证和 AI 服务的 HTTP 接口——这些都是外部资源,不算"系统混搭"。