提交 460aa4e5 authored 作者: 陈泽健's avatar 陈泽健

fix(服务自检): MQTT 主题订阅与消息推送检测恒失败修复

根因:订阅判定用 -match 'Connected'/'Subscribed',但 mosquitto_sub 从不输出这些文本,导致 7 个业务主题恒 0/7 失败;工具包架构硬编码 mqtt_test_x86;缺可执行性预检;推送判定靠文本匹配无端到端闭环。

修复:
- SSH uname -m 探测 → 自动选 mqtt_test_arm / mqtt_test_x86
- 上传后 ./mqtt version 预检,工具不可执行时明确报错并跳过
- 订阅判定改为以真实错误信号为失败基准(超时无消息=通道正常)
- 推送改为后台 sub -C 1 -v → pub → 校验订阅日志含测试消息

同步产出问题处理 + 计划执行双文档,更新 HANDOFF。Parser err=0、UTF-8 BOM、桌面字节级一致。
Co-Authored-By: 's avatarClaude <noreply@anthropic.com>
上级 8757a7c1
# _PRD_MQTT主题订阅与消息推送检测异常_问题处理
> 来源:
- `AuxiliaryTool\ScriptTool\ServiceSelfInspection\modules\MiddlewareCheck.psm1`
- `AuxiliaryTool/ScriptTool/ServiceSelfInspection/check_server_health.sh`(参考实现)
## 1. 背景与目标
### 1.1 背景
执行服务自检主脚本后,MQTT 测试工具上传成功,但 7 个业务主题**全部订阅失败(成功 0/7 个)**,消息推送检测也**一直失败**。该问题在多次执行中反复出现,从未成功过。
### 1.2 目标
修复 MQTT 主题订阅检测与消息推送检测的成功判定逻辑,确保:
- 主题订阅检测能正确识别"订阅成功 / 通道正常无消息 / 订阅失败"三种状态;
- 消息推送检测能正确验证消息端到端送达;
- 支持 ARM / x86 双架构服务器;
- 工具包不可执行时给出明确诊断信息而非误报失败。
---
## 2. 问题报错信息
### 2.1 问题一:主题订阅恒失败(成功 0/7)
```ignorelang
[2026-09-01 16:19:07] [INFO] [MQTT] 准备上传 MQTT 测试工具到远程服务器...
[2026-09-01 16:19:07] [SUCCESS] [MQTT] MQTT 测试工具上传完成
[2026-09-01 16:19:08] [INFO] [MQTT] ========== MQTT主题订阅检测 ==========
[2026-09-01 16:19:08] [WARN] [MQTT] 主题订阅失败或超时: /androidPanel/
[2026-09-01 16:19:08] [WARN] [MQTT] 主题订阅失败或超时: /iot/v1/conference/service/request/
[2026-09-01 16:19:08] [WARN] [MQTT] 主题订阅失败或超时: message/paperLessService/callService
[2026-09-01 16:19:08] [WARN] [MQTT] 主题订阅失败或超时: message/paperLessAuthor/onthewall
[2026-09-01 16:19:08] [WARN] [MQTT] 主题订阅失败或超时: /meeting/message/
[2026-09-01 16:19:08] [WARN] [MQTT] 主题订阅失败或超时: /iot/v1/device/event/request/
[2026-09-01 16:19:08] [WARN] [MQTT] 主题订阅失败或超时: /iot/v1/device/service/request/
[2026-09-01 16:19:08] [INFO] [MQTT] 主题订阅完成: 成功 0/7 个
```
### 2.2 问题二:消息推送恒失败
```ignorelang
[2026-09-01 16:19:08] [INFO] [MQTT] ========== MQTT消息推送检测 ==========
[2026-09-01 16:19:08] [INFO] [MQTT] 测试推送主题: /androidPanel/
[2026-09-01 16:19:08] [INFO] [MQTT] 测试消息内容: test_message_from_health_check_20260901161907
[2026-09-01 16:19:13] [WARN] [MQTT] 消息推送失败: /androidPanel/
```
### 2.3 关键线索
- `MQTT 测试工具上传完成` 为 SUCCESS 级别——工具上传链路正常,问题出在**工具执行后的结果判定**
- 每次运行时,同一批次 7 个主题**全部**失败——不符合"个别主题无人订阅/无消息"的预期,更像是**判定条件恒不成立****工具根本未执行成功**
- 工具包分别耗时约 5 秒(订阅)与 5 秒(推送),与 `timeout 5``sleep` 组合吻合,说明命令确实执行到了超时路径。
---
## 3. 问题解决分析
### 3.1 根因一:订阅成功判定条件与 mosquitto_sub 实际输出不符(主因)
**问题代码位置:** `MiddlewareCheck.psm1` 原第 287-306 行(方法D 主题订阅检测)
```powershell
$subCmd = "cd '$mqttToolDir' && export LD_LIBRARY_PATH='$mqttToolDir/lib':`$LD_LIBRARY_PATH' && timeout 5 ./mqtt sub -h localhost -t '$topic' -v 2>&1 || echo 'TIMEOUT'"
$subResult = Invoke-SSHCommand ...
if ($subResult.Output -and ($subResult.Output -match 'Connected' -or $subResult.Output -match 'Subscribed')) {
... 订阅成功 ...
} else {
... 订阅失败 ...
}
```
**分析:**
1. `mosquitto_sub` 是命令行的 MQTT 订阅客户端,**只在收到消息时输出消息内容**`-v` 时格式为 `topic payload`);
2.**从不输出** `Connected` / `Subscribed` 这类文本(与 mosquitto_pub 类似,连接成功是静默的);
3. 被检测的 7 个业务主题平时**无消息推送**,5 秒超时后无任何输出;
4. 因此 `-match 'Connected' -or -match 'Subscribed'` 条件**必然不成立**,无论 broker 是否正常、订阅是否成功,结果恒为"订阅失败"→ `成功 0/7 个`
**结论:** 当前判定逻辑是"必然失败"逻辑,与工具实际行为不符。
### 3.2 根因二:工具包架构硬编码为 x86,ARM 服务器上二进制无法执行
**问题代码位置:** `MiddlewareCheck.psm1` 原第 220-221 行
```powershell
$mqttToolDir = "/tmp/mqtt_test"
$mqttToolSrc = "mqtt_test_x86" # 硬编码,无架构判断
```
**分析:**
1. 仓库同时提供了 `mqtt_test_x86/`(musl 链接)与 `mqtt_test_arm/`(glibc aarch64)两个工具包;
2. shell 版 `check_server_health.sh` 第 1911-1918 行已有架构探测逻辑:`uname -m` 匹配 `arm|aarch64` → 选 `mqtt_test_arm`,否则 `mqtt_test_x86`
3. `MiddlewareCheck.psm1` 硬编码 `mqtt_test_x86`,若目标服务器为 ARM,上传的二进制**因可执行格式不符无法运行**
4. 同模块 `Test-FastDFSConnection`(第 1001-1006 行)已有 `uname -m` + `arm|aarch64` 架构选择的成熟先例可复用。
### 3.3 根因三:缺少工具可执行性预检,执行失败被误判为业务失败
**分析:**
1. shell 版在执行订阅/推送前先做版本预检(`mosquitto_pub --version`),工具不可用则降级或明确提示;
2. ps1 版上传后**不做任何预检**,直接开始订阅/推送;
3. 若二进制无法执行(架构不符、缺依赖库、权限异常),输出会包含 `cannot execute` / `error while loading shared libraries` / `No such file` 等错误,但现有判定只看 `Connected`/`Subscribed`,看不到这些诊断信息,只能笼统报"订阅失败",**掩盖了真正原因**
### 3.4 根因四:消息推送判定依赖文本匹配,缺乏端到端闭环验证
**问题代码位置:** `MiddlewareCheck.psm1` 原第 325-346 行(方法E 消息推送检测)
```powershell
$pubCmd = "cd '$mqttToolDir' && export LD_LIBRARY_PATH='$mqttToolDir/lib':`$LD_LIBRARY_PATH' && ./mqtt pub -h localhost -t '$testTopic' -m '$testMessage' 2>&1"
if ($pubResult.ExitCode -eq 0 -or ($pubResult.Output -match 'sent successfully' -or $pubResult.Output -match 'Connection closed')) {
```
**分析:**
1. `mosquitto_pub` 成功发送时**静默退出**(exit 0),不输出 `sent successfully`;而 `Connection closed` 在连接异常时反而可能出现,作为成功标志不可靠;
2. 推送检测只验证"发出去了"(单向),未验证"订阅端真的收到了这条消息"(端到端);
3. shell 版采用"后台订阅 `-C 1 -v` → 发布 → 校验收到消息内容与测试消息一致"的闭环验证,ps1 版未实现。
---
## 4. 解决分析总结
| 根因 | 问题代码位置 | 严重度 | 影响 |
|------|--------------|--------|------|
| 订阅成功判定条件与工具输出不符(`Connected`/`Subscribed` 从不输出) | `MiddlewareCheck.psm1` 方法D | 🔴 高 | 7 个主题恒 0/7 失败 |
| 工具包架构硬编码 `mqtt_test_x86` | `MiddlewareCheck.psm1:220-221` | 🔴 高 | ARM 服务器工具无法执行 |
| 缺工具可执行性预检 | 上传后、订阅前 | 🟠 中 | 执行失败被误判为业务失败,掩盖根因 |
| 推送判定文本匹配不可靠、无端到端闭环验证 | `MiddlewareCheck.psm1` 方法E | 🟠 中 | 推送结果误判 |
### 规范文档
- 代码规范: `Docs/PRD/01规范文档/_PRD_规范文档_代码规范.md`
- 问题总结: `Docs/PRD/01规范文档/_PRD_问题总结_记录文档.md`
- 方法总结: `Docs/PRD/01规范文档/_PRD_方法总结_记录文档.md`
- 文档规范: `Docs/PRD/01规范文档/_PRD_规范文档_文档规范.md`
- 测试规范: `Docs/PRD/01规范文档/_PRD_规范文档_测试规范.md`
---
*文档结束*
\ No newline at end of file
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论