# 智能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 | RAGFlow（M2） |
| 出站 | 新服务器 | `10.80.0.49` | 5000 | Qwen3-30B（M2） |
| 出站 | 新服务器 | 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 接口——这些都是外部资源，不算"系统混搭"。
