Files
getDomain/docs/ops_center_runtime/HANDOFF_20260420_1920.md
Your Name 7cbde2aa78 d
2026-04-22 14:13:21 +08:00

16 KiB
Raw Blame History

HANDOFF_20260420_1920

更新时间2026-04-20 19:20 CST

本轮结论

这轮最重要的收口已经完成:

  • 已确认当前工作机 /www/wwwroot/getDomain 所在主机是海外测试控制面,不是国内 mainland-controller-01
  • 已把“假冒 mainland-controller-01”的本机配置纠正为 overseas-control-01
  • 已把真正的 mainland-controller-01 重新接回控制面,并完成一次成功的远端发布
  • 已修正 mainland-controller-01 的 node-agent 身份上报问题
  • 现在控制面里看到的 mainland-controller-01 已经是真实主机:
    • hostname = mainland-controller-01
    • ip = 121.204.244.188

一句话说当前状态:

“主线已经从‘节点身份混乱’推进到‘真 controller 已经对正并重新进场’,下一步应只盯 controller 真机吞吐和 worker 恢复,不要再回展示层。”

当前环境认知

1. 当前 Codex 所在机器不是大陆 controller

本地执行结果:

  • hostname = v2202604268673447256
  • nproc = 12

这台机器是海外控制面测试机,不是用户说的 112 核 controller。

真正的国内 controller 是:

  • node_code = mainland-controller-01
  • ssh_host = 121.204.244.188

真正的国内 worker 是:

  • node_code = mainland-worker-01
  • ssh_host = 121.204.244.248

2. 本机服务身份已经纠正

为避免海外测试机继续伪装成 mainland controller已经改过这些环境文件

  • /etc/default/domaincheck-worker
  • /etc/default/domaincheck-node-agent
  • /etc/default/domaincheck-api

修正后的核心值:

  • NODE_CODE=overseas-control-01
  • NODE_REGION=overseas
  • SYNC_PUSH_ENABLED=false

并且已经执行过:

  • 停止本机 domaincheck-worker
  • 停止本机 domaincheck-node-agent
  • 重启本机 domaincheck-api

当前海外控制面 API 进程环境已确认是:

  • NODE_CODE=overseas-control-01
  • NODE_REGION=overseas

本轮已完成的关键修复

A. 修复 controller node-agent 上报 localhost / 127.0.0.1

修改文件:

修复内容:

  • _hostname() 不再优先相信 localhost
  • _ip() 不再使用容易得到 127.0.0.1 的旧逻辑
  • 优先通过控制面地址推导本机出口 IP
  • 回退时也会过滤 loopback

本轮新增/补过的测试:

注意:

  • 当前仓库里这份修复已经在真 controller 上生效
  • handover 已显示:
    • agent_hostname = mainland-controller-01
    • agent_ip = 121.204.244.188
    • cluster_hostname = mainland-controller-01
    • cluster_ip = 121.204.244.188

B. 修复 control 节点发布健康检查窗口过短

修改文件:

修改目标:

  • control 节点发布时,domaincheck-api 启动偏慢,旧健康检查窗口太短,会误判失败并回滚

代码里已改成:

  • health_check_timeout_seconds = 20
  • health_check_retries = 6
  • health_check_interval_seconds = 3

但要注意一个坑:

  • 这份代码虽然已改进源码
  • 海外控制面的运行中 API 进程还没有通过这份新源码重新部署
  • 所以 smart-rollout-preview 里看到的默认值一度仍然是旧的 10 / 2 / 2

因此本轮实际是通过“手工 remote-agent deploy job 显式带长窗口 payload”打通了 controller 发布。

C. 真 controller 发布已经成功一次

成功任务:

  • job_id = 331
  • job_code = ops-20260420183116-c33723
  • action = deploy.release
  • target_node_code = mainland-controller-01
  • execution_mode = remote-agent
  • status = success

本次使用的 release

  • release_id = 27
  • release_version = domaincheck_release_20260420_182916

发布结果要点:

  • 发布包下载成功
  • checksum 校验成功
  • /opt/domaincheck/current 切换成功
  • domaincheck-api / domaincheck-worker / domaincheck-sync-agent 重启成功
  • 健康检查最终通过

尤其要记住:

  • 这次成功不是靠 smart rollout 默认值
  • 是通过显式下发以下健康窗口打通的:
    • health_check_timeout_seconds = 20
    • health_check_retries = 6
    • health_check_interval_seconds = 3

D. controller node-agent 已经重新连回

后续又触发了:

  • job_id = 332
  • action = service.restart
  • payload.service_name = domaincheck-node-agent

这个任务本身还停留在 running,原因很正常:

  • node-agent 在“执行重启自己”的过程中会打断自身回执链
  • 所以作业状态可能不会自然收尾

但实际效果已经发生:

  • API 日志已看到 121.204.244.1882026-04-20 18:35:16 重新开始:
    • POST /api/v1/ops/agent/heartbeat
    • POST /api/v1/ops/agent/pull?limit=1

因此这条 job 332 可以视为“结果已生效,但状态未优雅回写”的典型自重启任务。

当前实机状态

按最新控制面查询:

mainland-controller-01

  • agent_online = true
  • cluster_status = busy
  • agent_hostname = mainland-controller-01
  • agent_ip = 121.204.244.188
  • current_load 在本轮观察中约 210 - 233
  • detect_runtime.active_threads 在本轮观察中约 210 - 233 / 2000
  • 已经有持续日志回传

mainland-worker-01

  • node-agent 在线
  • 但当前没有真正参与检测
  • 控制面返回的 detect_runtime 错误为:
    • connection to server at "127.0.0.1", port 5432 failed: Connection refused

这意味着:

  • worker 机现在不是主要算力来源
  • 目前真正吃任务的是 mainland-controller-01

当前主线瓶颈

目前主线已经不是“谁是 controller”了当前瓶颈明确是下面两个

  1. mainland-worker-01 未恢复到可参与检测状态
  2. mainland-controller-01 虽然真实线程已抬到 200+,但控制面队列视角仍存在:
    • claimed 偏高
    • running/completed 推进不够理想
    • 吞吐没有完全吃透机器

也就是说:

  • “节点身份问题”已基本打穿
  • “发布链路问题”已基本打穿
  • 下一步该只盯“真 controller 吞吐”和“worker 恢复”

本轮新增发现

1. mainland-worker-01 的 127.0.0.1:5432 更像是 node-agent 侧遥测链路问题

本轮继续排查后,发现这个问题至少有两层:

  1. domainCheck 默认配置本身就是:
    • DB_HOST = localhost
  2. worker 机上的 domaincheck-node-agent systemd unit 当前只加载:
    • /etc/default/domaincheck-api
    • /etc/default/domaincheck-node-agent

但大陆 worker 快速安装脚本真正写入数据库与 Redis 指向的是:

  • /etc/default/domaincheck-worker

也就是说worker 机上很可能出现这种情况:

  • domaincheck-worker 进程拿到的是正确的 DB_HOST=${MAINLAND_CONTROLLER_IP}
  • domaincheck-node-agent 没有继承 /etc/default/domaincheck-worker
  • node-agent 内部去跑 get_detect_status() 时,就会落回 domain-api 默认配置:
    • db_host = 127.0.0.1

于是控制面上看到的现象就变成:

  • mainland-worker-01 agent 在线
  • detect_runtime 里报:
    • connection to server at "127.0.0.1", port 5432 failed: Connection refused

2. node-agent 当前把“DB 查询失败”和“worker 进程离线”混成了一种失败

domain-api/app/node_agent.py 里的 _detect_runtime_snapshot() 原来是:

  • get_detect_status()detect_worker_runtime() 放在同一个总 try

这会导致:

  • 只要前面的 DB 查询失败
  • 后面的 worker systemd 运行态也一起被吞掉
  • 最终上报成:
    • worker_online = false
    • service_running = false

即使真实情况其实可能只是:

  • worker 服务还活着
  • 只是 node-agent 在采集 detect status 时查错 DB 了

3. 本轮已在源码里补的最小修复

已修改:

修复内容:

  1. _detect_runtime_snapshot() 改成分层降级:
    • 先拿 detect_worker_runtime()
    • 再单独尝试 get_detect_status()
    • 即使 detect status 因 DB 异常失败,也保留真实的 worker service 运行态
  2. domaincheck-node-agent.service 追加:
    • EnvironmentFile=-/etc/default/domaincheck-worker

这样 worker 机上的 node-agent 也能直接继承 worker 真实使用的 DB_HOST / REDIS_HOST

4. 这次修复的生效边界

要特别注意:

  • node_agent.py 代码修复可以通过常规 release 进入真实运行目录并生效
  • domaincheck-node-agent.service 属于 /etc/systemd/system/ 下的系统级 unit 文件
  • 常规 deploy.release 只会切换 /opt/domaincheck/current,不会自动重装 systemd unit

所以这两项应分开看:

  1. node_agent.py
    • 可以走最小 release 先上真机
  2. domain-node-agent.service
    • 需要后续补 systemd unit 落地动作
    • 至少要包含:
      • 覆盖 unit 文件或 drop-in
      • systemctl daemon-reload
      • systemctl restart domaincheck-node-agent

5. 本轮测试结果

已通过的焦点测试:

  • PYTHONPATH=/www/wwwroot/getDomain/domain-api /opt/domaincheck/domainCheck/.venv/bin/python -m unittest tests.test_node_agent_delivery_queue -v

结果:

  • 11 tests
  • OK

新增验证点:

  • test_detect_runtime_snapshot_degrades_to_worker_runtime_when_detect_status_fails

它验证了:

  • 即使 get_detect_status() 抛出
    • connection to server at "127.0.0.1", port 5432 failed
  • node-agent 依然会保留:
    • worker_online = true
    • service_running = true
    • phase_detail = active/running

本轮最小发布动作

1. 已生成新发布包

本轮最小修复已重新打包:

  • release_version = domaincheck_release_20260420_215734
  • release_id = 28

生成结果:

  • archive = /www/wwwroot/getDomain/release/domaincheck_release_20260420_215734.tar.gz
  • sha256 = ad2c41625503dab1efaeadbf0641c8f6875a3cad0581a3b9c7835ccc37cdc718

2. 已向真节点发起最小 release 下发

本轮只为把 node_agent.py 先推进真实运行目录,已创建:

  • job_id = 335
    • target = mainland-controller-01
    • action = deploy.release
  • job_id = 336
    • target = mainland-worker-01
    • action = deploy.release

这两条 job 都已经越过“等待拉取”,进入了 agent 执行阶段,并至少记录到:

  • executor_received
  • deploy_download_started

说明:

  • 真 controller 和真 worker 都已经接到了这版最小 release
  • 当前至少已经在真实节点上进入下载/发布链

3. 这次发布的真实目标

这次发布不是为了一次性解决所有 worker 恢复问题,而是为了先把下面这条代码修复推到真节点:

  • domain-api/app/node_agent.py

目的:

  • 即使 worker 节点的 detect_status 查询因 DB 指向错误失败
  • node-agent 也不再把真实的 worker service 运行态一并吞掉
  • 控制面能先看到更接近真实的 worker_online / service_running

4. 这次发布的限制

这次最小 release 暂时还不能自动完成下面这件事:

  • /etc/systemd/system/domaincheck-node-agent.service 更新为新版本

原因:

  • 常规 deploy.release 切的是 /opt/domaincheck/current
  • 不会自动重装 systemd unit

因此当前判断是:

  1. node_agent.py 代码修复:
    • 已经进入真实节点发布链
  2. domaincheck-node-agent.serviceEnvironmentFile=-/etc/default/domaincheck-worker
    • 仍需要后续单独补系统级落地动作

5. 当前发布观察结论

截至本次交接整理时:

  • job 335 / 336 已启动执行
  • 但尚未在本轮记录中拿到最终 success / failed 收尾结论
  • 因此后续接手时,先做的第一件事之一,就是复查这两条 job 的最终状态与事件流

当前不要再踩的坑

1. 不要再把本机当成 mainland-controller-01

当前工作机是海外测试控制面,只负责:

  • API
  • 控制面
  • 同步接收

不是 112 核大陆 controller。

2. 不要直接用本机 Python service 函数创建 deploy job

坑点:

  • 直接在 shell 里跑本地 Python 服务函数时,读取到的 settings.node_code 可能不是运行中 API 进程的真实环境
  • 之前就出现过把 job 错判为 local-runtime 的情况

正确做法:

  • 优先通过“正在运行的 API HTTP 接口”创建 job
  • 不要优先走本机 Python service 入口

推荐路径:

  • POST /api/v1/ops/releases/from-package/latest
  • POST /api/v1/ops/jobs
  • POST /api/v1/ops/jobs/{job_id}/dispatch

3. 不要把 job 332 当成硬故障

job 332service.restart domaincheck-node-agent

它卡在 running 不代表没生效,反而更像:

  • node-agent 重启了自己
  • 回执链没能把 job 收尾

判断是否真的生效,应看:

  • API 日志里有没有来自 121.204.244.188 的 heartbeat/pull
  • handover 里 agent_hostname / agent_ip 是否已刷新

4. 不要再回展示层

当前最值钱的推进方向仍然是:

  • controller 真机吞吐
  • claim/running/completed 推进
  • worker 恢复

不要把额度再耗在页面、文案、展示层结构上。

这轮动过的关键文件

最关键的源码文件:

此外,工作区还存在大量其他未提交改动,不要随意回滚:

  • domain-api/
  • domain-web/
  • domainCheck/
  • docs/ops_center_runtime/

这是一个脏工作区,接手时必须小心,不要用破坏性 git 命令。

建议下一个 Codex 只做的两件事

任务 1恢复 mainland-worker-01

目标:

  • mainland-worker-01 从“agent 在线但不参与检测”恢复到可执行检测

先查方向:

  • 为什么它在本地检测态里访问 127.0.0.1:5432 失败
  • 是本机 PostgreSQL 没启
  • 还是 worker 的运行配置仍然错误指向本地 DB
  • 还是它本来就不该走本地 PostgreSQL而应走远端/统一控制链

验收标准:

  • mainland-worker-01.detect_runtime.worker_online = true
  • mainland-worker-01.detect_runtime.active_threads > 0
  • 能稳定进入参与节点

任务 2继续抬 mainland-controller-01 真吞吐

目标:

  • 只盯真 controller 的任务推进链,不碰页面

重点看:

  • claimed -> running -> completed 是否持续推进
  • items_claimed 是否能下降
  • processed_recent / processed_per_minute 是否能抬起来
  • active_threadscompleted 是否成正相关

验收标准:

  • controller 持续有真实 completed 增长
  • running/claimed 更贴近“持续补位”而不是堆积
  • 机器性能使用能继续往上抬

可直接复用的验证点

1. 看节点 handover

接口:

  • GET /api/v1/ops/nodes/mainland-controller-01/handover

这一项已经能确认:

  • 当前是不是对到了真 controller
  • agent/ip/hostname 是否正确
  • 当前 load / detect_runtime 是否在动

2. 看节点列表

接口:

  • GET /api/v1/ops/nodes

重点字段:

  • agent_hostname
  • agent_ip
  • cluster_hostname
  • cluster_ip
  • detect_runtime.active_threads
  • current_load

3. 看海外控制面 API 日志

已验证有效:

  • journalctl -u domaincheck-api -n 200 --no-pager

尤其可以筛:

  • 121.204.244.188
  • /api/v1/ops/agent/heartbeat
  • /api/v1/ops/agent/pull

4. 发布 controller 的正确方式

推荐继续使用运行中的 API HTTP 接口,而不是本地 Python service 调用。

交接结论

这一轮真正解决掉的,不是“性能问题”本身,而是它前面最大的认知阻塞:

  • 之前一直有一部分判断建立在“本机就是 controller”这个错误前提上
  • 现在这个前提已经纠正
  • 真 controller 已经重新纳入控制面,而且身份上报正确、远端发布成功、线程也已经真实抬起来

接手人从这里继续时,应该把主线收缩成一句话:

“只盯 mainland-controller-01 的真实吞吐推进,并恢复 mainland-worker-01,不要再回展示层,也不要再把海外 12 核测试机当成主算力机。”