Files
memind/docs/g2-load-balancing.md
T
john 70492d9eba Add attachment text extraction, auto web news skill, and chat/voice UI updates.
Simplify asset upload temp paths, refresh deploy docs for Aliyun DNS topology, and ship MindSpace content-scan and auth improvements.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-20 15:08:10 +08:00

108 lines
5.4 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.
# g2.tkmind.cn 负载均衡(Studio + 105
> 2026-06-17 上线。把 g2 H5 的请求按权重分到两台机器:Studio(主)和 105(灰度副)。
> goose **只在 Studio 跑一份**105 是无状态前端孪生,通过 Tailscale 把请求代理回 Studio 的 goosed。
## 流量拓扑
```
用户 → 阿里云解析 → 105 服务器公网入口
├─ 转发到本地 Mac 1.6 机器 → 本机 portal 127.0.0.1:8081
└─ [SSH 正向隧道 127.0.0.1:18080] → 105 portal :8080
105 / 本地主机 两个 portal ── 都连 ──→ 本地 goosed 100.99.38.66:18006(唯一实例)
发布页文件 ── 都读 ──→ 本地 canonical /Users/john/Project/Memind/MindSpace
105 经反向隧道 + rclone 挂载到本地同路径)
```
- **为什么不用旧的 Cloudflare 直连**:当前入口已经迁到阿里云解析,外网流量先到 105,再由 105 转发回本地 Mac 1.6 机器。
- **为什么 105 经 SSH 隧道接入**:入口机和 105 之间保持本地 HTTP/SSH 链路,避免把 105 公网地址直接写进上游。
## 调灰度比例(最常用)
## 105 联通约束(硬性要求)
**要求:105 机器与本机通信必须走 Tailscale 隧道,不允许走外网 IP。**
- 访问、同步、部署 105 一律使用 `ssh105`
- `ssh105``~/.ssh/config` 中绑定为 `100.101.255.32` 并通过 `tailscale nc` 代理;
- 现有脚本默认主机已改为 `root@ssh105`
- 本机对 105 的联通入口是 `127.0.0.1:18080`,不是 `105.tkmind.cn`
快速自检(每次操作 105 前):
```bash
tailscale --socket /Users/john/Project/ollama/.tailscale/tailscaled.sock status
tailscale --socket /Users/john/Project/ollama/.tailscale/tailscaled.sock ping 100.101.255.32
ssh ssh105 'echo tunnel-ok-105'
curl -s http://127.0.0.1:18080/api/status # 应返回 ok
```
- 禁止:`HostName 120.26.184.105` 直接作为 105 脚本主机。
- 禁止:用 `105.tkmind.cn` 做 API 健康检查或同步链路入口。
编辑 **本地 Mac 1.6** 上的入口配置,调整流量分配(第一个=本机 :8081,第二个=105 :18080):
| 配置 | 本机 | 105 |
|------|------|-----|
| `weighted_round_robin 19 1` | 95% | 5%(默认上线值) |
| `weighted_round_robin 9 1` | 90% | 10% |
| `weighted_round_robin 4 1` | 80% | 20% |
| `weighted_round_robin 1 1` | 50% | 50% |
改完**零停机生效**
```bash
ssh 本机入口机
cd ~/Project/Memind/scripts
caddy validate --config g2-lb.Caddyfile # 可选,先校验
caddy reload --config g2-lb.Caddyfile # 零停机热重载
```
> `caddy` 路径若不在 PATH:用 `/opt/homebrew/bin/caddy`。
## 一键回滚(把流量全部收回 Studio)
`to` 那行的 `127.0.0.1:18080` 删掉(只留 `127.0.0.1:8081`),或直接恢复备份,然后 reload:
```bash
cd ~/Project/Memind/scripts
ls g2-lb.Caddyfile.bak-* # 找最近备份
cp g2-lb.Caddyfile.bak-XXXX g2-lb.Caddyfile
caddy reload --config g2-lb.Caddyfile
```
## 验证 / 观测
每个 g2 响应都带 `X-Memind-Upstream` 头,标记实际命中的上游(`127.0.0.1:8081`=本机,`127.0.0.1:18080`=105):
```bash
# 打 N 次看分流比例
for i in $(seq 1 40); do
curl -s -D - -o /dev/null https://g2.tkmind.cn/api/status \
| grep -i x-memind-upstream | awk '{print $2}' | tr -d '\r'
done | sort | uniq -c
# 看入口反代两个上游健康状态
curl -s http://127.0.0.1:2019/reverse_proxy/upstreams # 在本机入口机上执行
```
健康检查会每 10s 打一次各上游的 `/api/status`,连不上或非 200 就自动摘除该上游、流量全转到健康节点;恢复后自动加回。
## 涉及的组件与配置位置
| 组件 | 位置 | 作用 |
|------|------|------|
| 入口反代 | 本机入口机 `scripts/g2-lb.Caddyfile`LaunchAgent `cn.tkmind.g2-lb`,:8090) | 入口转发 + 健康检查 |
| 正向隧道 | 本机入口机 `scripts/memind-fwd-tunnel.sh`LaunchAgent `cn.tkmind.memind-fwd-tunnel` | 本机 `127.0.0.1:18080` → 105 `:8080` |
| 反向隧道 | 本机入口机 `scripts/memind-mac-tunnel.sh`LaunchAgent `cn.tkmind.memind-tunnel` | 105 经此挂载本地 MindSpace 文件 |
| 105 portal | 105 systemd `goose-h5`:8080),`/root/tkmind_go/ui/h5/.env` | 无状态前端,`TKMIND_API_TARGET=https://100.99.38.66:18006` |
| 105 文件挂载 | 105 systemd `.mount``/mnt/memind-shared`rclone over 反向隧道) | 发布页/工作区共享只读 |
## 关键约束(改动前必读)
- **105 永不跑 goose**。goosed 单实例只在本地 Mac 1.6 机器;session 存本地 SQLite,文件操作也在本地完成。105 只是代理 + serve。
- 105 的 portal 必须设 `MEMIND_WORKSPACE_MAINTENANCE=0``MINDSPACE_AGENT_JOBS_ENABLED=false`——工作区维护守护(缩略图/资产同步 watcher)只该在本地跑,否则 105 对 rclone 挂载树做递归 fs.watch 会占满 libuv 线程池导致 portal 启动卡死。
- 105 必须与本地主机跑**同一份代码**(用 `sync-to-105.sh` 从主机同步)和**相同的 `TKMIND_SERVER__SECRET_KEY`**(否则连不上 goosed / 解不开共享 RDS 里的加密设置)。
- 调权重只动 `g2-lb.Caddyfile`,不要动 105 的 systemd 单元或 .env。