跳转至

SOP —— 只读探测批量化(同主机拼 shell + 主机间并发 + 进程内缓存)

变更日期:2026-10-08 | 工程:monitoring-p2-20261001 关联:backup/probe-batch-20261008/(备份台账)| 运行见同目录 RUNBOOK.md

目录

  1. 背景 2. 目标 3. 前置条件 4. 影响范围
  2. 分步操作 6. 验证 7. 回滚 8. 风险说明

1. 背景

本工程的只读探测存在两类低效:

  • 主机间串行:utils/precheck.py::_check_hosts 对 16 台集群外主机逐台 ssh.run, 每台一次完整握手/执行,墙钟 ≈ 各台耗时之和。
  • 同主机多次往返:modules/host_filebeat.py::converge_one 对同一主机串行发起 3 次只读探测(包 probe_pkg → 配置 probe_config → 服务 probe_service), 3 次握手只为取 3 条短命令。deployer.py 的 cmd_verify / cmd_drift 同样逐台串行。

共享库 ~/py_public_modules/precheck_module.py 已提供两件通用能力(本次不改共享库):

  • build_probe_shell(probes) / parse_probe_output(raw, keys):把 {键: 命令} 拼成一段 shell(每段 echo '@@键' → 命令 → echo "@@rc_键=$?"),逐条退出码不失真;
  • ProbeBatch(ssh_exec):collect([...]) 只记录命令 → prefetch() 每台一条 shell (主机间并发)→ 之后 run(host, cmd) 命中缓存;未预取的命令自动回落逐条下发, 语义与改造前完全一致。

2. 目标

项 目标 判据
报告不变 precheck 报告逐项与改造前逐字一致 两次运行互 diff + 与改造前基线 diff 均为空(忽略时间戳)
三态不变 probe_pkg/config/service 的 done/pending/unknown 与返回文案不变 16 台逐台「串行 vs 批量」两两比对,mismatch=0
往返下降 converge_one 每台 3 次 → 1 次;跨主机循环并发 计数 harness:converge 48 → 16;precheck 墙钟 7.7s → 2.7s
顺序不变 报告行与 drift/verify 清单顺序与串行版一致 ThreadPoolExecutor.map 保序 / 并发取回后按原顺序 add

3. 前置条件

# 条件 说明
1 工程 venv 且 py_public_modules.pth 生效 python -c "import precheck_module" 可通
2 16 台集群外主机 SSH 可达 root 免密;本批实测全部可达
3 改前基线报告 改造前跑一次 main.py precheck 落 reports/,供逐项比对
4 备份 backup/probe-batch-20261008/ 存三份 .bak(600)

4. 影响范围

对象 动作 是否停服 是否触碰远端
utils/precheck.py _check_hosts 主机间并发、保序汇总 否 否(只读)
modules/host_filebeat.py probe_* 加可选 exec_ssh;converge_one 三探测合并为一条 shell 否 否(只读路径);变更类命令(install/write/restart)仍逐条串行
deployer.py cmd_verify / cmd_drift 跨主机只读循环并发 + 合并 否 否(只读)

边界:仅只读探测可并发/合并;rm、systemctl restart|reload、写文件、dnf install 等变更类命令保持逐条串行,未被并入任何批量 shell。

5. 分步操作

实现体改动(详见各文件注释);以下为关键点:

  1. _check_hosts:把每台的 ssh.run(script) 收敛为一个 _probe(node),用 ThreadPoolExecutor(max_workers=min(8, N)).map(...) 保序取回,再按原顺序处理, 报告行与串行版逐字一致。
  2. probe_pkg/config/service:新增 exec_ssh=None 形参,内部改走 (exec_ssh or self.ssh).run(...);默认行为不变,既有调用方无需改动。
  3. converge_one:先 render_config 得到 expected,用 ProbeBatch(self.ssh) collect 三个探测 → prefetch 一次取回 → 后续三次调用命中缓存。 缓存键 = (host, 命令原文),故三个探测的命令文本由配置确定性派生、预取与调用逐字相同。
  4. cmd_verify / cmd_drift:collect 全主机 → prefetch → 按原顺序回填 problems / drift / unknown。

⚠ 【新增坑·必读】 probe_pkg 的 rpm -q --qf '%{VERSION}' / dpkg-query -W -f='${Version}' 输出无换行,在批量 shell 里会与紧随其后的 echo "@@rc_p0=$?" 粘成一行 (8.19.0@@rc_p0=0),使退出码行不匹配、被 parse_probe_output 判为 unknown。 修复:格式串改为 '%{VERSION}\n' / '${Version}\n'(值后自带换行)。这是既有文档 「RPM --qf 粘行坑」在批量化下的新表现形式。

6. 验证

工程 venv 下执行:

cd /home/rain/Documents/k8s_ins/monitoring-p2-20261001
.venv/bin/python -c "import deployer, utils.precheck, modules.host_filebeat"   # 导入冒烟
.venv/bin/python main.py precheck && .venv/bin/python main.py precheck        # 两次回归
.venv/bin/python main.py drift ; .venv/bin/python main.py verify              # 只读路径

实测原始输出(2026-10-08):

  • 导入冒烟:import smoke OK,语言诊断 0 条。
  • 两次 precheck(135... 报告):diff(忽略时间戳)→ IDENTICAL; 与改造前基线 reports/precheck-20261008-133525.md diff → IDENTICAL。
  • 逐台三态等价:串行 serial_calls=48 vs 批量 batch_calls=16,mismatch_count=0 (rpm 主机 .16 与 deb 主机 .249 样例均为 done/pending/done)。
  • drift rc=0、verify rc=0;批量 shell 输出示例:@@p0\n8.19.0\n@@rc_p0=0(解析正确)。
  • 循环往返计数:converge 48 → 16;precheck 17(本就 1 台 1 次,靠并发降墙钟 7.698s → 2.744s)。

7. 回滚

改动全在操作机 Python 逻辑、未触远端、未改配置/清单,回滚即覆盖回原文件:

cd /home/rain/Documents/k8s_ins/monitoring-p2-20261001
cp backup/probe-batch-20261008/utils/precheck.py.bak.20261008-134056         utils/precheck.py
cp backup/probe-batch-20261008/modules/host_filebeat.py.bak.20261008-134056 modules/host_filebeat.py
cp backup/probe-batch-20261008/deployer.py.bak.20261008-134056              deployer.py

回滚后复跑 main.py precheck 应仍为「无 BLOCK 项」。

8. 风险说明

风险 评估 缓解
预取时机早于 install / write-config converge_one 在任何变更前取回三态。分析:install 不改 filebeat.yml 内容判定(缺失/变化均为 pending)、不改服务运行态;write-config 不启动服务。故决策与最终态不变 逐台串行/批量两两比对 mismatch=0;_install_pkg / write-config / restart 仍逐条串行,未被批量吞并
命令文本逐字一致 三探测命令均由配置确定性派生,collect 与调用处同源 缓存未命中即回落逐条,结论不变(仅无收益)
并发下的 SSH 连接池 SSHRunner.run 按 host 取连接,主机间并发互不干扰 实测 16 台并发 + verify/drift 均正常
nested ThreadPoolExecutor converge_all(5 并发)× 每台 ProbeBatch.prefetch(单台 1 worker) 单台仅 1 worker,无放大;实测通过
尚未在真实 deploy(非 dry-run)全链路验证 仅对只读路径(precheck/drift/verify/converge dry-run)取证 变更类命令未改动;建议下次变更窗口首跑 deploy --limit <单台> 观察

来源:/home/rain/Documents/k8s_ins/monitoring-p2-20261001/docs/SOP-parallel-probe.md | 最后更新:2026-10-08 13:46(由 build/sync.py 同步,请勿在站点侧修改)