故障排查
按「先退出码/回执、再端口面、再集群面」的顺序定位问题。本页的每条路径都对应 一个确定的信号源——不猜。
第一现场:退出码(worker 启动失败)
| 退出码 | 语义 | 典型原因 |
|---|---|---|
| 10 | 引导失败(装载/校验拒绝) | worker.json 未知字段(拼错)、H3 能力闸、DP-only 互斥、raft 段缺三要素 |
| 11 | 绑定失败 | 数据口/管理口端口被占、权限不足 |
| 12 | 运行期致命 | 未处理异常(看 stderr 堆栈) |
| 0 | 干跑通过/干净停机 | — |
| 2/3 | 干跑用法错误/校验失败 | validate 动词专用档 |
启动失败的stderr 第一行就是人读原因(例如:worker 配置未知字段:listen.protts—— schema↔With 一一映射,拼错即拒绝)。先读它,再动手。
配置写了不生效:看发布回执
一切实体先 draft、发布才生效——「改了没生效」九成是没发布或发布被拒:
traffic-worker publish status # 当前世代/双水位/最近任务
traffic-worker publish dry-run # 重新预检,看结构化 issues
干跑回执的 issues[] 带 {entityType, key, field, message}——精确到字段:
{"entityType":"orch","key":"demo-chain","message":"缺少必填字段 'links'。","field":"links"}
关键不变量:编译拒绝=旧世代继续服务。发布失败不会把线上流量打断——
修复 draft 重新发布即可。回滚走 publish rollback(翻回上一世代或指定世代)。
端口面排查
| 症状 | 信号源 |
|---|---|
| 管理命令全部「管理口不可达」 | admin 口没起(DP-only 节点零管理口=TUI 不适用——显式报错) |
| 数据口 503 | 节点活着但无 published 配置——发布一次 |
| 某路由 404 | 路由未发布/条件不匹配/enabled:false(编译剔除面)——route simulate 干跑路由匹配 |
| H3 客户端不升级 | 防火墙 UDP 未放行(同号 TCP 通 UDP 断)——见HTTP/3 |
集群面排查
traffic-worker cluster status # 一切集群问题的第一动作
| 症状 | 看什么 |
|---|---|
| 写命令 409 | KernLab.Traffic.Cluster.NotLeader 信封——按信封里的 Leader 提示重发 |
| DP 没流量/配置旧 | 复制水位是否追平、/readyz 是否 503(未追平=刻意摘除) |
| 成员消失 | 最后心跳列(信令在证/复制在证/活性窗三口径) |
| 选举抖动 | Voter 数量(至少 3)+Tier 口连通性(恒内网) |
测试/巡检命令
traffic-worker validate --config worker.json # 配置干跑(与启动同装载器——零漂移)
traffic-worker route conflicts # 路由冲突/遮蔽检索(对运行快照静态分析)
traffic-worker target list --cluster <code> # 上游目标运行态(健康/摘除/在途/权重)
traffic-worker metrics errors # per-status-code 计数——错误分布现场
traffic-worker trace query --route <code> # 近窗执行链路——step 级失败现场
路由匹配仿真(route simulate,请求体 {method,path,host?} 对运行快照投影):
echo '{"method":"GET","path":"/x"}' | traffic-worker route simulate <route>。
测试卡死/进程挂起
测试或运维脚本出现疑似挂起(≥5 分钟无输出):先取证再杀进程——
dotnet-stack report -p <pid> 抓全线程栈定性等待链;烧 CPU 型加
dotnet-trace 采样。取证文件是定位根因的第一现场,杀进程前必须落盘。