Add smart ACK provider for WeChat MP replies
Replace fixed ackText with a rule-based AckProvider that picks response templates by message type and intent (translate, summary, rewrite, poster, ppt, mindmap, code, search, schedule). Pure sync, zero I/O, auto-falls back to config.ackText on any error. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+39
-307
@@ -1,315 +1,47 @@
|
||||
# Memind 生产更新发布指南
|
||||
# Memind Portal 生产更新发布指南
|
||||
|
||||
> 本文描述如何把本地开发代码安全发布到 **g2.tkmind.cn** 生产环境。
|
||||
> 发布前请先阅读 [生产 / 测试 / 预览隔离规程](./service-isolation-runbook.md),避免误占生产端口或覆盖用户数据。
|
||||
> 2026-06-26 起,103 / Studio 正式禁止 `rsync` 发布。
|
||||
> Portal 生产必须是**无源码 runtime 模式**,唯一合法入口是 `bash scripts/release-portal-runtime-prod.sh`。
|
||||
|
||||
## 1. 架构与发布目标
|
||||
## 当前规则
|
||||
|
||||
用户访问 `https://g2.tkmind.cn/` 的流量路径:
|
||||
1. 构建只发生在本机 Mac:`node scripts/build-portal-runtime.mjs`。
|
||||
2. 103 只接收 `.runtime/portal/` 打出来的 artifact,不直接覆盖源码树。
|
||||
3. 103 在切换前必须做 `Memind` 全量备份,并单独备份持久目录。
|
||||
4. 103 **禁止** `npm install`、`npm run build`、在线改源码后继续运行。
|
||||
5. 切换后必须通过 Portal 健康检查;失败立即回滚。
|
||||
|
||||
```text
|
||||
阿里云解析(DNS)
|
||||
→ 105 服务器(公网入口 / 反代)
|
||||
→ 本地 Mac 1.6 机器(主服务)
|
||||
├─ 主流量 → 本地 Portal(127.0.0.1:8081)
|
||||
└─ 备用/灰度 → 105 Portal(经隧道 127.0.0.1:18080 → :8080)
|
||||
```
|
||||
|
||||
两台 Portal 都是 **无状态前端**,共用 Studio 上的 goosed 与 MindSpace 数据目录。
|
||||
|
||||
```mermaid
|
||||
flowchart TB
|
||||
Dev[本地开发目录] -->|rsync_to_server.sh| Studio[Studio 生产机<br/>/Users/john/Project/Memind]
|
||||
Studio -->|sync-to-105.sh| N105[105 入口 / 反代]
|
||||
N105 -->|g2.tkmind.cn| G2[g2 H5 / Portal]
|
||||
N105 -->|plaza.tkmind.cn| Plaza[Plaza 前台]
|
||||
N105 -->|gadm.tkmind.cn| Gadm[memind_adm]
|
||||
G2 --> Portal[Portal :8081]
|
||||
Plaza --> PlazaSrv[Plaza :3001]
|
||||
Gadm --> AdmSrv[memind_adm :8082]
|
||||
```
|
||||
|
||||
| 角色 | 机器 | 代码目录 | 服务 | 重启方式 |
|
||||
|------|------|----------|------|----------|
|
||||
| 生产主 | 本地 Mac 1.6 机器 | `/Users/john/Project/Memind` | Portal `:8081`、Plaza `:3001` | `launchctl kickstart` |
|
||||
| 入口转发 | 105 服务器 | 入口转发配置 | 反代 `:80/:443` | 阿里云解析切换后生效 |
|
||||
| 灰度副 | 105(经 Tailscale `ssh105`) | `/root/tkmind_go/ui/h5` | `goose-h5` `:8080` | `systemctl restart goose-h5` |
|
||||
|
||||
更详细的流量与灰度比例说明见 [g2 负载均衡](./g2-load-balancing.md)。
|
||||
|
||||
## 2. 目录与环境对照
|
||||
|
||||
| 环境 | 典型目录 | 端口 | 用途 |
|
||||
|------|----------|------|------|
|
||||
| **生产(Studio)** | `/Users/john/Project/Memind` | `8081` / `3001` | 线上 g2 / plaza |
|
||||
| **开发预览** | `/Users/john/Project/test/Memind` 或本机副本 | `18081` / `13001` | 本地联调,禁止占 `8081` |
|
||||
| **105 副机** | `/root/tkmind_go/ui/h5` | `8080` | g2 灰度流量 |
|
||||
|
||||
**重要:** `rsync_to_server.sh` 会把**你执行命令时所在的本地目录**同步到 Studio 生产目录。发布前请确认当前目录里的代码就是你要上线的版本,而不是半成品或未验证的分支。
|
||||
|
||||
## 3. 发布入口(主流程)
|
||||
|
||||
**推荐唯一入口:** 项目根目录的 `rsync_to_server.sh`
|
||||
## 唯一入口
|
||||
|
||||
```bash
|
||||
cd /path/to/your/memind-repo # 开发完成、已自测的目录
|
||||
|
||||
# ① 预览(不修改任何远端)
|
||||
./rsync_to_server.sh --dry-run
|
||||
|
||||
# ② 正式发布(Studio + 105 全量)
|
||||
./rsync_to_server.sh
|
||||
bash scripts/release-portal-runtime-prod.sh --dry-run
|
||||
bash scripts/release-portal-runtime-prod.sh
|
||||
```
|
||||
|
||||
脚本会自动完成:
|
||||
|
||||
1. 本地 Pre-flight(关键文件、安全 patch、exclude 规则)
|
||||
2. Studio Pre-flight(SSH、`.env`、MindSpace、data 完整性)
|
||||
3. 交互确认(可用 `--yes` 跳过)
|
||||
4. rsync 代码 → Studio 生产目录
|
||||
5. rsync 后校验(`.env` 未变、MindSpace 未减少、patch 仍在)
|
||||
6. Studio 上 `npm install` + `npm run build`
|
||||
7. 重启本地 Mac 1.6 Portal → Plaza,并做健康检查
|
||||
8. 经 Studio 触发 `scripts/sync-to-105.sh`,同步并重启 105
|
||||
|
||||
## 4. 发布前检查清单
|
||||
|
||||
在 `./rsync_to_server.sh` 之前,逐项确认:
|
||||
|
||||
### 4.1 本地构建与测试
|
||||
|
||||
```bash
|
||||
pnpm install # 依赖有变更时
|
||||
pnpm run build # 前端改动必须能编过
|
||||
pnpm test # 建议跑;涉及核心逻辑时必跑
|
||||
```
|
||||
|
||||
| 改动类型 | 是否必须 build | 能否 `--skip-build` |
|
||||
|----------|----------------|---------------------|
|
||||
| 前端(`.tsx` / `.css` / `src/`) | **是** | 否 |
|
||||
| 仅后端(`.mjs`) | 否(但 build 无害) | 可以 |
|
||||
| 仅文档 / 脚本 | 否 | 可以 |
|
||||
|
||||
### 4.2 生产在线(只读)
|
||||
|
||||
```bash
|
||||
curl -s http://127.0.0.1:8081/api/status # 本地 Portal,期望 ok
|
||||
curl -s http://127.0.0.1:18080/api/status # 105 隧道,期望 ok
|
||||
```
|
||||
|
||||
105 联通必须走 Tailscale,不要用公网 IP:
|
||||
|
||||
```bash
|
||||
ssh ssh105 'echo tunnel-ok-105'
|
||||
```
|
||||
|
||||
### 4.3 安全约束(脚本会自动检查)
|
||||
|
||||
- `server.mjs` 必须含 `WORKSPACE_MAINTENANCE_ENABLED` patch(否则 105 重启会在 rclone 挂载上卡死)
|
||||
- `.env`、`MindSpace/`、`data/` 在 exclude 列表中,**不会被 rsync 覆盖**
|
||||
- rsync 使用 `--delete`:本地已删的文件会从 Studio 删掉(exclude 外的路径)
|
||||
|
||||
### 4.4 发布范围确认
|
||||
|
||||
- `rsync_to_server.sh` 同步的是**整个仓库**(除 exclude 外),不是单个文件
|
||||
- 工作区若有未完成的其它改动,会一并上线——发布前建议 commit 或整理干净
|
||||
- 涉及数据库迁移、批量清数据、支付回调测试等,**不要**直接在生产目录试跑,见 [隔离规程](./service-isolation-runbook.md)
|
||||
|
||||
## 5. 分步与保守发布
|
||||
|
||||
`rsync_to_server.sh` 支持的常用参数:
|
||||
|
||||
| 参数 | 作用 | 适用场景 |
|
||||
|------|------|----------|
|
||||
| `--dry-run` | 只预览 diff,不改远端 | **每次正式发布前必做** |
|
||||
| `--only-100` | 只更新本地主机,不推 105 | 先让主流量生效,105 稍后 |
|
||||
| `--only-105` | 只触发本地主机→105 同步 | 主机已是最新,只补 105 |
|
||||
| `--skip-build` | 跳过远端 `npm run build` | 纯后端改动且确认 dist 无需更新 |
|
||||
| `--no-restart` | 只同步代码,不重启服务 | 分批发布;需自行重启 |
|
||||
| `--yes` / `-y` | 跳过交互确认 | 自动化或你已看过 dry-run |
|
||||
|
||||
示例:
|
||||
|
||||
```bash
|
||||
# 只发 Studio(主流量 95%)
|
||||
./rsync_to_server.sh --only-100
|
||||
|
||||
# 纯 server.mjs 改动,跳过 build
|
||||
./rsync_to_server.sh --skip-build
|
||||
|
||||
# 先同步代码,稍后再重启
|
||||
./rsync_to_server.sh --no-restart
|
||||
# 之后在 Studio 上手动 kickstart,或再跑一遍带重启的同步
|
||||
```
|
||||
|
||||
## 6. 105 单独同步
|
||||
|
||||
若 Studio 代码已是最新,只需更新 105:
|
||||
|
||||
```bash
|
||||
# 在 Studio 生产目录执行
|
||||
cd /Users/john/Project/Memind
|
||||
bash scripts/sync-to-105.sh
|
||||
|
||||
# 或从本地只触发 105 链路
|
||||
./rsync_to_server.sh --only-105
|
||||
```
|
||||
|
||||
`sync-to-105.sh` 会:
|
||||
|
||||
1. rsync 代码(`--delete`)与 `dist/` 到 `root@ssh105:/root/tkmind_go/ui/h5`
|
||||
2. 远端 `npm install` + `npm run build`(可用 `SKIP_BUILD=1` 跳过)
|
||||
3. `systemctl restart goose-h5`
|
||||
4. 校验关键文件 md5 与 `:8080/api/status`
|
||||
|
||||
环境变量(可选):
|
||||
|
||||
| 变量 | 默认值 | 说明 |
|
||||
|------|--------|------|
|
||||
| `H5_DEPLOY_HOST` | `root@ssh105` | 105 SSH 目标 |
|
||||
| `H5_REMOTE_DIR` | `/root/tkmind_go/ui/h5` | 105 代码路径 |
|
||||
| `H5_SYSTEMD_SERVICE` | `goose-h5` | systemd 服务名 |
|
||||
| `SKIP_BUILD` | `0` | `1` 跳过远端 build |
|
||||
| `NO_RESTART` | `0` | `1` 不重启服务 |
|
||||
|
||||
package.json 中的 `pnpm deploy:105` 等价于本地执行 `bash scripts/sync-to-105.sh`(需本机能 SSH 到 105,或已在 Studio 上)。
|
||||
|
||||
## 7. 发布过程与影响窗口
|
||||
|
||||
全量 `./rsync_to_server.sh` 典型耗时 **5~10 分钟**。
|
||||
|
||||
| 阶段 | 用户可见影响 |
|
||||
|------|----------------|
|
||||
| rsync + npm install + build | 无(旧进程仍在跑) |
|
||||
| 本地 Portal 重启 | **8081 短暂不可用**,约 10~40 秒;主流量可能短暂 502 |
|
||||
| 105 goose-h5 重启 | **灰度流量(约 5%)** 短暂不可用 |
|
||||
| Plaza 重启 | plaza.tkmind.cn 可能短暂不可用;与 g2 主聊天无关 |
|
||||
|
||||
入口反代会对不健康上游做健康检查,105 重启期间可能暂时从池中摘除。
|
||||
|
||||
## 8. 发布后验证
|
||||
|
||||
### 8.1 健康检查
|
||||
|
||||
```bash
|
||||
curl -s http://127.0.0.1:8081/api/status
|
||||
curl -s http://127.0.0.1:18080/api/status
|
||||
curl -s https://g2.tkmind.cn/api/status
|
||||
```
|
||||
|
||||
### 8.2 确认命中哪台上游
|
||||
|
||||
g2 响应头 `X-Memind-Upstream`:
|
||||
|
||||
- `127.0.0.1:8081` → 本地 Mac 1.6 机器
|
||||
- `127.0.0.1:18080` → 105
|
||||
|
||||
```bash
|
||||
curl -s -D - -o /dev/null https://g2.tkmind.cn/api/status | grep -i x-memind-upstream
|
||||
```
|
||||
|
||||
### 8.3 业务冒烟
|
||||
|
||||
按本次改动选手动验证,例如:
|
||||
|
||||
- 打开 g2 聊天页,测试新功能
|
||||
- 登录 / 微信 OAuth(若动到 auth)
|
||||
- MindSpace 页面读写(若动到 pages)
|
||||
- Plaza 列表(若动到 plaza)
|
||||
|
||||
### 8.4 日志
|
||||
|
||||
```bash
|
||||
# 本地 Portal
|
||||
tail -f ~/Library/Logs/memind-portal.log
|
||||
|
||||
# Studio Plaza
|
||||
tail -f ~/Library/Logs/plaza-prod.log
|
||||
|
||||
# 105(经 ssh105)
|
||||
ssh ssh105 'journalctl -u goose-h5 -n 50 --no-pager'
|
||||
```
|
||||
|
||||
## 9. 回滚思路
|
||||
|
||||
项目没有一键回滚脚本,常见做法:
|
||||
|
||||
1. **代码回滚:** 在本地 git 回到上一个 good commit,`./rsync_to_server.sh` 再发一版
|
||||
2. **仅本地主机:** 若 105 有问题,可临时把流量全部收回主机(见 [g2-load-balancing.md](./g2-load-balancing.md))
|
||||
3. **紧急恢复 Portal:** 若 8081 挂了,见 [隔离规程 · 事故恢复](./service-isolation-runbook.md#事故恢复最小步骤)
|
||||
|
||||
发布前建议打 tag 或记录当前 commit,便于回滚:
|
||||
|
||||
```bash
|
||||
git rev-parse HEAD
|
||||
git tag -a release-2026-06-19 -m "before voice UI deploy"
|
||||
```
|
||||
|
||||
## 10. 其它发布路径(非 g2 主站)
|
||||
|
||||
### 10.1 同步到局域网测试机
|
||||
|
||||
仅源码同步到 `192.168.1.9` 上的 test 目录,**不是生产**:
|
||||
|
||||
```bash
|
||||
bash scripts/deploy-to-test-host.sh --dry-run
|
||||
bash scripts/deploy-to-test-host.sh
|
||||
```
|
||||
|
||||
目标:`test-memind` / `test-memindadm` / `test-memindplaza`。同步后需按该机习惯手动重启服务。
|
||||
|
||||
### 10.2 Plaza 105 入口转发
|
||||
|
||||
```bash
|
||||
pnpm deploy:plaza-105
|
||||
```
|
||||
|
||||
`plaza.tkmind.cn` 一样是 `105 -> Studio` 的入口模式,只是它对应的是 Plaza 前台而不是管理后台。
|
||||
当前真实链路见 [Plaza 入口与发布](./plaza-local.md)。
|
||||
|
||||
### 10.3 gadm / memind_adm
|
||||
|
||||
`gadm.tkmind.cn` 的生产入口和 Plaza 相同,也是 `105 -> Studio`。
|
||||
更完整的操作手册见 [gadm 入口与发布](./gadm-local.md)。
|
||||
|
||||
### 10.4 已废弃 / 不可用
|
||||
|
||||
| 命令 | 状态 |
|
||||
|------|------|
|
||||
| `pnpm deploy:prod` | 指向 `../../deploy/deploy-h5-prod.sh`,当前仓库旁路不存在,**勿用** |
|
||||
|
||||
## 11. 推荐发布 SOP(标准作业)
|
||||
|
||||
适合大多数功能迭代的固定步骤:
|
||||
|
||||
```text
|
||||
1. 在测试端口完成开发与自测(18081,勿占 8081)
|
||||
2. pnpm run build && pnpm test
|
||||
3. ./rsync_to_server.sh --dry-run ← 看清将要同步什么
|
||||
4. 确认无多余改动、无数据库破坏性操作
|
||||
5. ./rsync_to_server.sh ← 全量 Studio + 105
|
||||
6. curl 健康检查 + 浏览器冒烟
|
||||
7. 观察 5~10 分钟日志,确认无 ERROR 尖峰
|
||||
```
|
||||
|
||||
**保守版(先主后副):**
|
||||
|
||||
```text
|
||||
1~4 同上
|
||||
5. ./rsync_to_server.sh --only-100
|
||||
6. 冒烟通过后
|
||||
7. ./rsync_to_server.sh --only-105
|
||||
```
|
||||
|
||||
## 12. 相关文档
|
||||
|
||||
| 文档 | 内容 |
|
||||
|------|------|
|
||||
| [service-isolation-runbook.md](./service-isolation-runbook.md) | 生产 / 测试端口隔离、禁止事项、事故恢复 |
|
||||
| [g2-load-balancing.md](./g2-load-balancing.md) | g2 权重、105 隧道、灰度比例调整 |
|
||||
| [local-dev.md](./local-dev.md) | 本地开发端口与 preview |
|
||||
| [plaza-local.md](./plaza-local.md) | Plaza 部署与 Tunnel |
|
||||
|
||||
---
|
||||
|
||||
**维护说明:** 若部署脚本路径、主机名或 systemd 服务名变更,请同步更新本文与 `rsync_to_server.sh` 头部注释。
|
||||
## 产物发布流程
|
||||
|
||||
1. 本地 commit 当前改动。
|
||||
2. 本机构建 runtime:`node scripts/build-portal-runtime.mjs`(发布脚本默认会自动执行)。
|
||||
3. 校验 artifact 至少包含:`server.mjs`、`mindspace-sandbox-mcp.mjs`、`dist/`、`scripts/run-memind-portal-prod.sh`。
|
||||
4. 本地生成 `memind-portal-runtime-<release-id>.tar.gz` 和发布清单。
|
||||
5. 通过 `scp` 上传到 103 的 `incoming/memind-portal-runtime/`。
|
||||
6. 103 备份当前 `/Users/john/Project/Memind` 全目录 + 持久目录。
|
||||
7. 停止旧 Portal,解包 runtime artifact 到新的 live 目录,继承 `.env` / `MindSpace/` / `data/` / `users/` / `.tailscale/` / `public/plaza-covers/` / `logs/`。
|
||||
8. 更新 LaunchAgent 指向 `${APP_DIR}/scripts/run-memind-portal-prod.sh`。
|
||||
9. 启动 Portal,检查 `127.0.0.1:8081/api/status` 为 200。
|
||||
10. 旧源码 live 目录移入 `archives/`,线上不再保留可运行源码树。
|
||||
|
||||
## 禁止事项
|
||||
|
||||
- 禁止 `rsync_to_server.sh`
|
||||
- 禁止 `bash scripts/release-prod.sh`(源码包发布已停用)
|
||||
- 禁止手工拖文件覆盖 103
|
||||
- 禁止在 103 直接改源码后继续跑
|
||||
- 禁止跳过备份和健康检查
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [Portal 无源码迁移说明](no-source-portal-migration.md)
|
||||
- [开发环境规则](../DEVELOPMENT_RELEASE_RULES.md)
|
||||
- [测试发布规则](../TEST_RELEASE_RULES.md)
|
||||
- [生产发布规则](../PRODUCTION_RELEASE_RULES.md)
|
||||
|
||||
Reference in New Issue
Block a user