82 lines
3.7 KiB
Markdown
82 lines
3.7 KiB
Markdown
# 换协议端那天:文件发送整体故障,以及"我把它弄哑了"
|
||
|
||
**发现时间**:2026-09-14 20:39(晚间快照时段)
|
||
**当前状态**:✅ 已修复(20:47 验证通过)
|
||
**影响任务**:主人的文件发送、以及**一位朋友的期货回测交付**(20:04~20:46 连续十三次失败)
|
||
|
||
---
|
||
|
||
## 一、现象
|
||
|
||
主人问「你怎么不能发出文件了」。复现后报错非常干脆:
|
||
|
||
```
|
||
ENOENT: no such file or directory,
|
||
realpath '/AstrBot/data/workspaces/.../file_test.txt'
|
||
```
|
||
|
||
关键诊断动作:**把对方自己上传给我的那份文件再发回去——同样 ENOENT**。
|
||
那份文件百分百在磁盘上 → 所以**不是路径写错,是"发文件"这个功能整体失效**。
|
||
|
||
前后共试 **13 次**:3 个不同目录、2 种扩展名,全部失败。
|
||
|
||
---
|
||
|
||
## 二、根因(两层)
|
||
|
||
### 第一层:新协议端没有挂载 AstrBot 的数据目录
|
||
|
||
- AstrBot 递过去的是**它自己容器内的路径**(`/AstrBot/data/...`)。
|
||
- 旧协议端当年**特意挂载了 AstrBot 的数据目录**,所以能"看见"这些文件。
|
||
- 这次迁移时**我漏了这一条挂载** → 新协议端那边那个路径是空的 → 文件"不存在"。
|
||
|
||
### 第二层(真正的坑):修它的方式,会把登录态弄掉
|
||
|
||
补挂载必须**重建容器**。而重建新协议端容器 = **QQ 登录态丢失**。
|
||
|
||
于是报错从 `ENOENT` 变成了:
|
||
|
||
```
|
||
aiocqhttp.exceptions.ApiNotAvailable
|
||
```
|
||
|
||
—— AstrBot 认为"这个 API 不可用",因为**承载 API 的那条通道已经断了**(登录没了,节点未激活,反向连接没建立)。
|
||
|
||
---
|
||
|
||
## 三、为什么我绕了很久
|
||
|
||
我在**错误的方向**上排查了:端口监听、节点配置文件、容器网络、DNS 解析——**全都对,就是不通**。
|
||
|
||
最后是**截了一张 QQ 桌面的图**,才看见屏幕上明晃晃一个**二维码**。
|
||
→ **掉登录了。**
|
||
|
||
> 教训:当"配置全对但就是不通"时,**先去确认最基础的那一层状态(登录态)**,而不是继续深挖配置。
|
||
|
||
---
|
||
|
||
## 四、处置步骤(可复用)
|
||
|
||
1. **先复现**,拿到确切报错;
|
||
2. **交叉验证**:用"对方上传的文件"回发,区分"路径错"与"功能坏";
|
||
3. 补挂载 AstrBot 数据目录到协议端容器(**两个路径都要对齐**,覆盖 AstrBot 容器内视角与宿主机视角两种写法);
|
||
4. **⚠️ 重建容器前必须先打招呼**——QQ 会掉登录,需要重新扫码;
|
||
5. 验证三件事:协议端容器内能 `ls` 到文件 → 反向连接已建立 → 实际发一次;
|
||
6. **旁路兜底**:故障期间改用"把脚本压成几十行的内联版本"让对方直接复制,不要让交付完全停摆。
|
||
|
||
---
|
||
|
||
## 五、沉淀(写进肌肉记忆)
|
||
|
||
- 🔴 **重建新协议端容器 = 掉登录**。以后改它的配置,先问一句"现在方便扫码吗"。
|
||
- 🔴 协议端的**真实节点配置是那个带账号名的文件**,不是默认的那份。第一遍我看了默认文件,白绕一圈。
|
||
- 🟡 **文件发送依赖"协议端能看见 AstrBot 的数据目录"**——这是一条隐式依赖,迁移协议端时**必须逐条对照旧容器的挂载表**,不能只看文档。
|
||
- 🟡 故障期间**能立刻给的最小可用版本,比一句"我在修"值钱**。
|
||
|
||
---
|
||
|
||
## 六、当晚顺带记录的两条同源经验
|
||
|
||
- **公网暴露的窗口只有二十秒**:新协议端起来二十来秒,VNC 端口就被一个陌生外部地址摸到(密码验证失败挡住)。→ 立即收回本机回环,只放开需要的那一个入口。
|
||
- **VNC 口令只有前 8 位有效**(协议本身的 8 字节限制)。给 16 位强密码,实际生效的是前 8 位——这类"我以为是 A、实际是 B"的事,**必须实测**。
|