fix: 停机先停接受并等待循环再断开 MQTT

This commit is contained in:
Nixevol
2026-09-30 16:22:44 +08:00
parent 6a65ab8593
commit b40ef5c548
8 changed files with 345 additions and 20 deletions
+9
View File
@@ -471,6 +471,15 @@
- 备选方案:metrics 失败锁定管理员 IP。
- 影响:锁定按真实客户端 IP;TLS 重连可 DidResume。
### 复审修复 L-03
1. **有 MQTT 连接时停机**
- 原条款:DEVELOPMENT 7.8;issue #22。
- 实际做法:listener 拆成 `StopAccept()`(关 TCP 监听并对 HTTP 调 Shutdown)和带超时的 `Wait(ctx)`(超时强关仍阻塞在 `OnMQTT` 的连接)。`serve` 在 `<-ctx.Done()` 后立刻调用 `stop()`;顺序为 StopAccept → 取消并等待消息循环 → Drain(10 秒)→ `brk.Shutdown`(5 秒)→ 用剩余时间再 Drain → `Wait` → `db.Close()`。compose `stop_grace_period: 30s`;OPS 写明 systemd `TimeoutStopSec` 至少 30 秒。未改 `PublishDown` 签名。
- 原因:原先 `Close` 的 `wg.Wait` 会卡在裸 TCP/WS 的 `AttachTCP`/`AttachWS`,连 Drain 都走不到;`signal.NotifyContext` 的 stop 要等 `cmdServe` 返回才调用,卡住期间第二次 SIGTERM 被吞掉。
- 备选方案:先强关全部 MQTT 再 HTTP Shutdown(会丢在途 HTTP)。
- 影响:保持已登录 TCP/WS 客户端时 `runServe` 应在约 15 秒内返回,客户端收到 DISCONNECT `0x8B`。
## 消息 M
### M1 2026-09-30
+1
View File
@@ -122,6 +122,7 @@ curl -sS -H "Authorization: Bearer $NIXMSG_METRICS_TOKEN" http://127.0.0.1:7443/
- 容器以 uid `65532` 运行:挂载数据目录须可写;命名卷首次可
`docker run --rm -v <卷名>:/data busybox chown -R 65532:65532 /data`。
- 首次:`docker compose run --rm nixmsg admin init`,再 `up -d`。
- Compose 示例已设 `stop_grace_period: 30s`。systemd 单元请设 `TimeoutStopSec=30`(或更长),以便进程先停接受、排空写队列并下发 MQTT DISCONNECT `0x8B`。第二次 Ctrl+C / SIGTERM 会按默认行为结束进程。
- 构建/推送 Task 目标见根目录 README(`q:docker-build` / `q:docker-push` / `q:docker-buildx`)。正式仓库推送在阶段 3。
## 9. 验收与仍跳过的长时项