Skip to content

v3.18.1

Choose a tag to compare

@github-actions github-actions released this 28 Aug 13:52
· 11 commits to master since this release

修复:迁移前的 pm2 fleet 在编译版下漏杀,以及随之暴露的永久误报

从 pm2 版 botmux 升级上来的机器,botmux restart 会先停掉仍活着的旧 pm2 God,
再由新 supervisor 拉起自己的 daemon。本次修掉这条迁移路径上三个叠加的缺陷 ——
它们共同的后果是新旧两套 fleet 同时消费同一批飞书事件:同一个 appId 被两个
进程长连接、IPC 与终端端口互相挤占、两套同时持有同一个 session sqlite(实测报
SessionStoreUnavailableError: disk I/O error,消息处理真的失败)。

1. 编译版单文件二进制下 reap 完全空转

resolvePm2Bin 先探 <pkgRoot>/node_modules/pm2/bin/pm2,而 pkgRoot
__dirname 推导 —— 编译态下它在虚拟 /$bunfs/ 里,探针必然落空,随后返回裸
'pm2' 交给 PATH。编译版不带 pm2,于是每次 spawn 都 ENOENT、被 best-effort 吞掉:
既不 delete 也不 kill。失败只写 logger.info,而 CLI 模式下 logger 是静音的,
操作者看不到任何提示restart 照常拉起第二套 fleet。

改为:编译态直接判定无 CLI,转而读 God 自己的 PM2_HOME/pids/ 记录并直接收进程
(那份记录一直在盘上,reap 本就不需要 pm2)。杀进程顺序是先 God 后 daemon ——
反过来会被仍活着的 God 当场 respawn。发信号前一律校验 cmdline,避免 pid 复用误伤;
kill(pid,0) 对 zombie 返回成功,因此判活额外排除 zombie 状态。无法确认旧 fleet
已停时,通过 stderr 明确告警,不再谎报成功。

2. reap 成功后告警永久误报,重跑也清不掉

pm2 kill 会删 pm2.pid 却把 rpc.sock 留在磁盘上,而检测在无 pid 文件时只判
socket 文件是否存在;无 CLI 的信号路径又不删 pm2.pid,而刚被杀的 God 此刻是
zombie。两者都让「已经死掉的 God」被读成活的 —— 于是 status/logs 每次都提示
去做一件已经完成的迁移。

改为:判断 socket 是否真被进程持有,reap 成功后清掉两个残留记录(仍指向活进程的
文件不动),并把 status/logs 的告警判据合并到 reaper 导出的同一个检测函数 ——
此前那是同一逻辑的第二份手工副本,正是它漂移导致告警在成功迁移后依然说谎。

3. musl(Alpine)二进制上,上面两处修复同样空转

判据原本 shell out 到 ps -plsof <路径>,而这两个在 Alpine 上是 BusyBox
applet、语义不同:ps 不支持 -p(退 1 空输出,于是 pid 守卫拒掉每一个进程,
reap 找不到任何可收的东西),lsof 完全忽略路径参数(恒退 0 有输出,于是孤儿
socket 被判成活 God,误报清不掉)。musl 二进制自 v3.18.0 起是正式发布产物之一。

改为:Linux 下统一读 /proc/proc/<pid>/cmdline/proc/<pid>/stat
/proc/net/unix),macOS 保留 ps/lsof 分支。/proc 是内核接口,glibc 与 musl
行为一致,且不再依赖 lsof(在精简镜像里常常压根不存在);socket 探测顺带从一次
约 1.5 秒的进程全扫降为一次文件读。

其它

  • resolvePm2Bin 探测 pm2 是否可用时补上显式的一次性 PM2_HOMEpm2 --version
    并非只读操作,它会 daemonize 一个 God,继承环境会把它建在调用方的 pm2 home 里。
  • 新增 scripts/smoke-musl-reaper-probes.mjs,在 CI 与发布流程的 Alpine 容器中各跑
    一次。这类缺陷单元测试原理上抓不到 —— 测试跑在 glibc 上,把判据改回 ps/lsof
    依然全绿。
  • 相关测试从 17 项扩到 25 项,补齐此前无覆盖的几处:真实孤儿 socket、被持有的
    socket、探测用的 pm2 home 隔离,以及 pm2 CLI 路径上「先 delete 再 kill」的顺序。

影响面限于 legacy pm2 迁移路径及其检测,不涉及 CLI 适配器、会话后端、会话类型或
IM 层;macOS 行为不变。


✨ 新功能

  • history: 按会话范围提示搜索边界与扩大方式 (#1002)
  • dashboard: 开发机自动提供私有访问入口 (#1060)

🐛 修复

  • release: Release 先建草稿,二进制附完再公开,消除 curl 安装的 404 窗口 (#1062)
  • lark: 关闭卡片会话恢复时不再强制发卡 (#1058)
  • fleet: 编译版 botmux restart 不再漏杀迁移前的 pm2 fleet (#1064)
  • release: 去掉注释里的撇号,musl 腿不再因外层单引号提前闭合而语法错误 (b19f7e4)

🙏 感谢贡献者

@tuomao @LucasIcarus @swtxbling

Full Changelog: v3.18.0...v3.18.1