16 KiB
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-01ip = 121.204.244.188
一句话说当前状态:
“主线已经从‘节点身份混乱’推进到‘真 controller 已经对正并重新进场’,下一步应只盯 controller 真机吞吐和 worker 恢复,不要再回展示层。”
当前环境认知
1. 当前 Codex 所在机器不是大陆 controller
本地执行结果:
hostname = v2202604268673447256nproc = 12
这台机器是海外控制面测试机,不是用户说的 112 核 controller。
真正的国内 controller 是:
node_code = mainland-controller-01ssh_host = 121.204.244.188
真正的国内 worker 是:
node_code = mainland-worker-01ssh_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-01NODE_REGION=overseasSYNC_PUSH_ENABLED=false
并且已经执行过:
- 停止本机
domaincheck-worker - 停止本机
domaincheck-node-agent - 重启本机
domaincheck-api
当前海外控制面 API 进程环境已确认是:
NODE_CODE=overseas-control-01NODE_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-01agent_ip = 121.204.244.188cluster_hostname = mainland-controller-01cluster_ip = 121.204.244.188
B. 修复 control 节点发布健康检查窗口过短
修改文件:
修改目标:
- control 节点发布时,
domaincheck-api启动偏慢,旧健康检查窗口太短,会误判失败并回滚
代码里已改成:
health_check_timeout_seconds = 20health_check_retries = 6health_check_interval_seconds = 3
但要注意一个坑:
- 这份代码虽然已改进源码
- 海外控制面的运行中 API 进程还没有通过这份新源码重新部署
- 所以
smart-rollout-preview里看到的默认值一度仍然是旧的10 / 2 / 2
因此本轮实际是通过“手工 remote-agent deploy job 显式带长窗口 payload”打通了 controller 发布。
C. 真 controller 发布已经成功一次
成功任务:
job_id = 331job_code = ops-20260420183116-c33723action = deploy.releasetarget_node_code = mainland-controller-01execution_mode = remote-agentstatus = success
本次使用的 release:
release_id = 27release_version = domaincheck_release_20260420_182916
发布结果要点:
- 发布包下载成功
- checksum 校验成功
/opt/domaincheck/current切换成功domaincheck-api / domaincheck-worker / domaincheck-sync-agent重启成功- 健康检查最终通过
尤其要记住:
- 这次成功不是靠 smart rollout 默认值
- 是通过显式下发以下健康窗口打通的:
health_check_timeout_seconds = 20health_check_retries = 6health_check_interval_seconds = 3
D. controller node-agent 已经重新连回
后续又触发了:
job_id = 332action = service.restartpayload.service_name = domaincheck-node-agent
这个任务本身还停留在 running,原因很正常:
- node-agent 在“执行重启自己”的过程中会打断自身回执链
- 所以作业状态可能不会自然收尾
但实际效果已经发生:
- API 日志已看到
121.204.244.188在2026-04-20 18:35:16重新开始:POST /api/v1/ops/agent/heartbeatPOST /api/v1/ops/agent/pull?limit=1
因此这条 job 332 可以视为“结果已生效,但状态未优雅回写”的典型自重启任务。
当前实机状态
按最新控制面查询:
mainland-controller-01
agent_online = truecluster_status = busyagent_hostname = mainland-controller-01agent_ip = 121.204.244.188current_load在本轮观察中约210 - 233detect_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”了,当前瓶颈明确是下面两个:
mainland-worker-01未恢复到可参与检测状态mainland-controller-01虽然真实线程已抬到 200+,但控制面队列视角仍存在:claimed偏高running/completed推进不够理想- 吞吐没有完全吃透机器
也就是说:
- “节点身份问题”已基本打穿
- “发布链路问题”已基本打穿
- 下一步该只盯“真 controller 吞吐”和“worker 恢复”
本轮新增发现
1. mainland-worker-01 的 127.0.0.1:5432 更像是 node-agent 侧遥测链路问题
本轮继续排查后,发现这个问题至少有两层:
domainCheck默认配置本身就是:DB_HOST = localhost
- worker 机上的
domaincheck-node-agentsystemd 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 = falseservice_running = false
即使真实情况其实可能只是:
- worker 服务还活着
- 只是 node-agent 在采集 detect status 时查错 DB 了
3. 本轮已在源码里补的最小修复
已修改:
- domain-api/app/node_agent.py
- domain-api/deploy/systemd/domain-node-agent.service
- domain-api/tests/test_node_agent_delivery_queue.py
修复内容:
_detect_runtime_snapshot()改成分层降级:- 先拿
detect_worker_runtime() - 再单独尝试
get_detect_status() - 即使 detect status 因 DB 异常失败,也保留真实的 worker service 运行态
- 先拿
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
所以这两项应分开看:
node_agent.py:- 可以走最小 release 先上真机
domain-node-agent.service:- 需要后续补 systemd unit 落地动作
- 至少要包含:
- 覆盖 unit 文件或 drop-in
systemctl daemon-reloadsystemctl 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 testsOK
新增验证点:
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 = trueservice_running = truephase_detail = active/running
本轮最小发布动作
1. 已生成新发布包
本轮最小修复已重新打包:
release_version = domaincheck_release_20260420_215734release_id = 28
生成结果:
archive = /www/wwwroot/getDomain/release/domaincheck_release_20260420_215734.tar.gzsha256 = ad2c41625503dab1efaeadbf0641c8f6875a3cad0581a3b9c7835ccc37cdc718
2. 已向真节点发起最小 release 下发
本轮只为把 node_agent.py 先推进真实运行目录,已创建:
job_id = 335target = mainland-controller-01action = deploy.release
job_id = 336target = mainland-worker-01action = deploy.release
这两条 job 都已经越过“等待拉取”,进入了 agent 执行阶段,并至少记录到:
executor_receiveddeploy_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
因此当前判断是:
node_agent.py代码修复:- 已经进入真实节点发布链
domaincheck-node-agent.service的EnvironmentFile=-/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/latestPOST /api/v1/ops/jobsPOST /api/v1/ops/jobs/{job_id}/dispatch
3. 不要把 job 332 当成硬故障
job 332 是 service.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/app/node_agent.py
- domain-api/app/services/ops_release_service.py
- domain-api/tests/test_node_agent_delivery_queue.py
此外,工作区还存在大量其他未提交改动,不要随意回滚:
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 = truemainland-worker-01.detect_runtime.active_threads > 0- 能稳定进入参与节点
任务 2:继续抬 mainland-controller-01 真吞吐
目标:
- 只盯真 controller 的任务推进链,不碰页面
重点看:
claimed -> running -> completed是否持续推进items_claimed是否能下降processed_recent / processed_per_minute是否能抬起来active_threads与completed是否成正相关
验收标准:
- 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_hostnameagent_ipcluster_hostnamecluster_ipdetect_runtime.active_threadscurrent_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 核测试机当成主算力机。”