Files
MailUI4Agents/deploy/systemd/opencode-serve.service.d/zz-restart-backoff.conf
JianFeeeee 51789ee72e deploy: 标准目录部署 —— 运行时不再依赖源码目录
用户注意到:「当前 agentmail 是在源码目录部署的,应当改为标准目录部署」。
查证后有三处实证(都不是猜测):

1. ★ **失败通知钩子执行的是仓库里的脚本**
   (`/home/program/agentmail/deploy/service-failure-notify.mjs`,8 处引用:
   4 个 drop-in + zcode/zcode-mail-bridge 单元 + agentmail-failure-flush)。
   仓库一挪/一改名,故障通知就**静默失效** —— 而那条管线正是用来报告服务故障的。
2. **opencode-serve 的 cwd 就是源码目录**(`WorkingDirectory=/home/program/agentmail`)。
3. ★ **仓库里的 `deploy/*.service` 是旧的源码目录版本**(ExecStart 指向
   `/home/program/agentmail/plugins/...`),而机器上的已被改过 —— 也就是说
   **谁跑一次 install.sh 就会把部署退回源码目录**。drop-in 更是只存在于 /etc 里,
   仓库完全没有它们。

## 改动

- **唯一真相**:`deploy/systemd/` 镜像 systemd 目录结构,收进全部单元与 drop-in
  (8 个单元 + 12 个 drop-in),路径全部改到 `/opt`。
- 运行时脚本装到 **`/opt/agentmail/bin/service-failure-notify.mjs`**(自包含,
  无相对导入);`install.sh` 与 `redeploy-gateway.sh` 都会幂等地装它。
- opencode 的 cwd 改为 `/opt/agentmail`(与网关一致),已重启生效
  (`/proc/<pid>/cwd` 已核)。
- 删掉 `deploy/*.service` 的旧副本,避免两个真相。
- dsh 的 `cordis.patch.yml` 注释里的安装示例也改到标准位置(运行时用的是环境变量,
  那条注释是唯一残留)。

## 判据(`deploy/check-deploy-drift.mjs` 新增「标准目录部署」四条 + 自检)

① 任何 unit/drop-in 都不得引用源码目录;② 已安装单元与 `deploy/systemd/` 逐字节一致;
③ 通知脚本在标准位置且可执行;④ 各服务的 cwd/ExecStart 不在源码目录
(homeagent/dsh/zcode 是**别的产品**的标准位置,按白名单放行)。
自检两个样本:引用源码目录的必须红、干净样本必须绿(证明不是恒真)。

顺带修掉一处**真漂移**:仓库里 dsh 的 `dist/index.js` 落后于部署件(改了 src 没重建),
重建后 `check-deploy-drift` 报「四个宿主都在跑当前代码」。

## 复核

- `/etc/systemd/system/` 引用仓库:**0** 个文件;`/opt/agentmail` 下只剩旧二进制/备份里
  的构建路径(Go 嵌的源码路径,无害)与一条注释。
- 四个宿主都在跑当前代码;标准目录四项全绿。
- 全部服务 active,opencode/网关 cwd 均已在安装根下。
2026-09-14 08:38:33 +08:00

24 lines
1.4 KiB
Plaintext
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.

# 2026-09-05 systemd 审计添加的 drop-in原单元文件未改动
#
# 为什么加:本机的重启限速器其实是死代码。
# StartLimitBurst=5 + StartLimitIntervalUSec=10s 的含义是「10 秒内启动 5 次
# 就放弃」,但这些单元的 RestartSec 都在 2~10s 之间 —— 5 次重启必然跨过
# 10 秒,计数器每次都在触发前清零。于是一个永久坏掉的服务会以固定频率
# 无限重试systemd 从头到尾不会说一句话。
#
# 实测后果2026-09-05 07:5409:13llmsproxy 因为 config.yaml 里 headers
# 键重复而无法解析、退出码 1systemd 每 5 秒拉一次,连拉 79 分钟 ——
# 836 次重启,占掉本次启动 986 条 "Failed with result" 里的 901 条,
# 而 "start request repeated too quickly" 一次都没出现过。
#
# 怎么修:改成指数退避。重试间隔从该单元自己的 RestartSec 出发,经 RestartSteps
# 级递增到 RestartMaxDelaySec崩溃循环会衰减到每 5 分钟一次。服务不会被放弃
# (病根修好后它仍会自己回来),日志也不再被刷爆。
#
# 故意不动的东西StartLimitBurst / StartLimitIntervalUSec。收紧它们会让故障单元
# 进入终态 failed、必须人工 systemctl reset-failed 才能复活 —— 这正好和这些
# 长驻 agent 依赖的自愈行为相反。
[Service]
RestartSteps=6
RestartMaxDelaySec=5min