architecture.md 138→116 行:删除 §9「当前实现与上线门槛」(进度内容,归 invariants 声明边界与 Plane,其中部署前提并入 §8);§4 主流程压成链路摘要 + design 节名指针,去掉与 design 重复的机制细节;§8 可观测性收成一句并把指标口径指向 reference;D1–D4 第三列由「当前状态」改为「证据 / 缺口」稳定 ID 指针。 reference.md:模块入口补 infra/metrics/JobActivity.kt、infra/health/JobRunnerHealthIndicator.kt 与 config/OperationDayProps.kt;迁移清单补 V7–V9。
12 KiB
参考注册表:参数、指标、模块、错误分类
本文件是可派生事实的唯一出处:参数默认值、指标名、模块入口、错误分类。正文(design.md)只引 PARAM:<完整键>,不写数值。
维护规则:新增或改名一个 msgx.* 键、增删一个指标名,必须同步本文件(人工核对,本项目不做 CI 校验)。mailbox.*、datasources.*、kafka.* 属基础设施键,按 §1.3 成组登记。
1. 参数注册表
「依据」列含义:契约 = 由 contracts.md 的 C-x 决定;现役 = 沿用 legacy 行为基线;假定 = 无依据的占位值,必须在对应 Q 关闭后重评;安全默认 = 关闭态,需显式开启。
1.1 管道节奏与重试(msgx.pipeline.*)
| 参数 | 默认 | 单位 | 依据 | 说明 |
|---|---|---|---|---|
msgx.pipeline.poll-interval |
1s |
Duration | 现役 | 收报轮询节奏;决定队头与空洞检查频率 |
msgx.pipeline.claim-batch |
50 |
条 | 假定 | 单轮领取上限;过大延长单轮事务 |
msgx.pipeline.max-attempts |
5 |
次 | 假定 | 处理与投递共用;达到即转 DEAD(EXHAUSTED) |
msgx.pipeline.backoff-ms |
[1000,2000,4000,8000] |
ms / 档 | 假定 | 档位数必须 = max-attempts − 1,启动自检拦截错位 |
msgx.pipeline.backoff-cap-ms |
60000 |
ms | 假定 | 单档封顶;默认表内无档触及 |
msgx.pipeline.max-commit-delay |
5m |
Duration | 假定(无依据) | 空洞老化阈值;由 C-2 决定,不可由 SIS Expiry 推导(Q2) |
msgx.pipeline.overdue-backfill(R) |
30d |
Duration | 契约(R ≤ R_keep) |
进入强补写窗口、取消退避的阈值;不是兜底保证,不保护重放窗口(Q6) |
msgx.pipeline.backfill-batch |
100 |
条 | 假定 | 回填扫描单批条数 |
msgx.pipeline.backfill-scan-period |
30s(代码常量,无配置键) |
Duration | 现役 | 回填扫描作业周期;批次积压与单行超时会延长实际标记延迟(CLM-9) |
msgx.pipeline.backfill-max-attempts |
100 |
次 | 假定 | 单行重试的告警阈值;放弃判据是 R 超期,不是次数(见 design「回填」) |
msgx.pipeline.backfill-backoff-ms |
目标参数(未实现) | ms / 档 | 假定 | 回填独立退避表;当前不存在,BackfillService 内硬编码 30 秒起步、封顶 15 分钟 [G-BACKFILL-BACKOFF] |
msgx.pipeline.backfill-backoff-cap-ms |
目标参数(未实现) | ms | 假定 | 回填退避封顶;对应实现是代码内常量,尚无配置键 [G-BACKFILL-BACKOFF] |
msgx.pipeline.cutover-watermark |
不设置 | min|zero|max|<id> |
一次性运维决策 | 显式播种水位;非法值由启动自检挡下;升级实例拒绝重新播种 |
msgx.pipeline.late-detect-period |
60s |
Duration | 假定 | 只读迟到检测周期;≤0 关闭;机制为临时观测(见 design 扫描路径) |
msgx.pipeline.late-detect-batch |
200 |
条 | 假定 | 每轮复查的空洞 ID 上限 |
msgx.pipeline.delivery-batch |
200 |
条 | 假定 | KAFKA:msg 每轮每目标领取上限 |
msgx.pipeline.delivery-drain-rounds |
10 |
轮 | 假定 | 连取批数上限,让出循环跑 schd flush,防状态通知被积压饿死 |
msgx.pipeline.autostart |
false |
布尔 | 安全默认 | 启动即拉起收报 / 主泵 / 投递循环;需真实仓储或 msgx.stubs=true |
msgx.pipeline.event-retention |
目标参数(未实现) | Duration | 假定 | 已 SENT 事件行保留期,由维护作业清理;缺失则 outbox 无限增长 [G-EVENT-RETENTION] |
1.2 其它 msgx.*
| 参数 | 默认 | 依据 | 说明 |
|---|---|---|---|
msgx.service-name |
msgexchangeapi |
契约冻结 | 服务注册名;影子实例用独立名 |
msgx.register-eureka |
true |
现役 | 服务注册开关;影子对拍期置 false |
msgx.stubs |
true(dev profile) |
安全默认 | 内存适配器;生产禁止,生产 profile 不设置该键 |
msgx.schd.flush-period |
3s |
现役 | schd 聚合周期 |
msgx.schd.flush-limit |
500 |
假定 | 聚合批上限 |
msgx.operation-day.zone |
Asia/Shanghai |
现役 | 运营日推导时区;配置值非法时启动失败,不使用代码字面量回退 |
msgx.operation-day.cutoff-hour |
0 |
假定(占位) | 切日边界;待业务确认 |
msgx.identity.include-day-boundary |
false |
安全默认 | 身份是否加日期边界;影响去重语义,不能当调优项切换(Q11) |
msgx.health.backlog-cache-ttl-ms |
30000 |
假定 | 积压快照缓存窗口;0 = 不缓存;/health 与 /metrics 共用同一快照 |
msgx.history.history-store-enabled |
false |
安全默认 | 历史存储门控;关闭时历史清理删 0 条 |
msgx.history.cancelled-hours |
48 |
假定 | 历史清理的取消态判据窗口 |
msgx.history.terminal-hours |
48 |
假定 | 历史清理的终态判据窗口 |
msgx.history.deleted-hours |
48 |
假定 | 历史清理的已删除判据窗口 |
msgx.history.idle-hours |
168 |
假定 | 历史清理的静默期判据 |
msgx.history.snap-log-retention-days |
90 |
假定 | SCHD_SNAP_LOG 保留天数 |
msgx.proc-state.archive-after |
1d |
假定 | 未实现([G-PROC-HST]);终态记录归档阈值,建议范围 1~7 天;见 US-11 |
1.3 信箱与外部依赖(成组登记)
| 参数组 | 默认 | 依据 | 说明 |
|---|---|---|---|
mailbox.processed-value |
PROCESSED |
契约(C-5/Q7) |
处理标记写入值;仅限库方认可值集 |
mailbox.shared-mysql.enabled |
false |
安全默认 | 真实信箱接线门控 |
mailbox.shared-mysql.connect-timeout-ms / socket-timeout-ms |
3000 / 30000 |
假定 | 有界外部调用;Connector/J 默认无限等待,必须显式 |
mailbox.shared-mysql.pool-connection-timeout-ms / pool-validation-timeout-ms |
5000 / 3000 |
假定 | 池级超时 |
mailbox.shared-mysql.url / username / password |
环境变量 | 安全 | 零入库,见 .env.example |
datasources.default.connection-timeout / validation-timeout / idle-timeout / max-lifetime |
5000 / 3000 / 300000 / 1800000 |
假定 | 自有 PG 池(毫秒数,非 Duration 字面量) |
datasources.default.data-source-properties.connectTimeout / socketTimeout |
3 / 30 |
假定 | 驱动级超时(秒),防网络黑洞 |
kafka.producers.default.acks |
all |
契约(architecture D3) | 允许环境变量覆盖 |
kafka.producers.default.enable-idempotence |
true |
契约(D3) | 允许环境变量覆盖 |
kafka.producers.default.max-in-flight-requests-per-connection |
5 |
与 D3 不一致 | D3 要求 1;切流前必须收敛 [G-KAFKA-D3] |
环境变量清单以 .env.example 为准。
2. 指标与健康
| 指标 | 含义 | 期望方向 |
|---|---|---|
msgx.pipeline.backlog.unfinished |
未处理完的消息条数 | 长期 > 0 且不降 → 积压 |
msgx.pipeline.backlog.oldest_unprocessed_seconds |
最老未处理消息的信龄 | 持续增长 → 队头卡住 |
msgx.pipeline.backfill.unmarked_terminal |
已终态但未打标的条数 | 不降 → 回填失败 |
msgx.pipeline.backfill.abandoned |
已放弃自动回填的条数 | 非 0 需人工对账 |
msgx.pipeline.backfill.oldest_unmarked_seconds |
最老待回填年龄 | 决定实际回填延迟 |
msgx.pipeline.watermark.lag |
水位落后信箱最新 ID 的距离 | 增长 → 收报停滞 |
msgx.pipeline.hole.aged_out.total |
永久空洞放行次数 | 突增 → ID 序列大量空位 |
msgx.pipeline.late_arrival.detected.total |
迟到到达命中数 | > 0 表示上游提交确实晚于水位推进,需要与库方对契约 |
msgx.pipeline.job.heartbeat_age_seconds |
距上一次作业 tick 完成的秒数(未跑过为 -1) | 持续增长 → 作业线程卡死 |
msgx.pipeline.job.last_failure_age_seconds |
距最近一次作业 tick 失败的秒数(从未失败为 -1) | 配合 failures.total 增长判断扫描/历史作业异常 |
msgx.pipeline.job.ticks.total |
作业 tick 完成次数 | 不增长 → 作业停摆 |
msgx.pipeline.job.failures.total |
作业 tick 抛错次数 | 增长 → 扫描/历史作业异常 |
msgx.pipeline.job.last_sweep_selected |
上一轮回填扫描选中的待办条数(扫描积压) | 持续顶到批次上限 → 扫描吃不消 |
取数规则:统一走 BacklogSnapshotProvider(PARAM:msgx.health.backlog-cache-ttl-ms),/health 与 /metrics 共用同一快照——backlog() 是 PROC_STATE 的全表聚合,不能被高频抓取打穿;无法取数上报 NaN,无可比记录的年龄/滞后类仪表上报 -1,都不伪造 0。日志出口故障不得阻塞业务线程。
作业健康:回填的唯一驱动是扫描作业,因此作业存活必须独立可观测——msgx.pipeline.job.heartbeat_age_seconds / ticks.total / failures.total 是作业心跳,msgx.pipeline.job.last_sweep_selected 是扫描积压,msgx.pipeline.backfill.oldest_unmarked_seconds 是实际回填延迟;作业线程停摆由 /health 的作业指示器判 DOWN(心跳超过 3 × 扫描周期,周期是代码常量)。
3. 模块入口
| 关注点 | 主要入口 |
|---|---|
| 收报与兼容接口 | ingress/InboxPoller.kt、InboxService.kt、InboxController.kt |
| 解码 | codec/JacksonXmlCodec.kt、SisWireMapper.kt、SisMessageBody.kt |
| 调度与处理 | processing/Pump.kt(含 MessageProcessor)、DynamicProcessors.kt(FLOP/FDEL/ADFT)、Identity.kt |
| 日计划 | processing/ScheduleProcessor.kt;请求协调尚无实现(REQ_TRACK 仓储见 infra/persistence/) |
| 回填与投递作业 | processing/BackfillService.kt、jobs/JobRunner.kt、HistorySweepJob.kt、delivery/Dispatcher.kt |
| 持久化与恢复 | infra/persistence/、infra/retry/(ProcFailure / ReplayService / FailureScheduler) |
| 启停与配置 | PipelineLifecycle.kt、config/PipelineProps.kt、config/HistoryProps.kt、config/OperationDayProps.kt(含运营日时区启动自检) |
| 指标与健康 | infra/metrics/PipelineMetrics.kt、infra/metrics/JobActivity.kt、infra/health/BacklogSnapshotProvider.kt、infra/health/JobRunnerHealthIndicator.kt |
| 迁移 | src/main/resources/db/migration/(V1 基线、V2 生命周期、V3 稳定处理起点、V4 回填闭环、V5 切流播种、V6 本地入队时间、V7 删除处理起点、V8 REQ_TRACK 开放态唯一索引、V9 schd 单行化;oracle11g/ 为占位) |
4. 错误分类与重放白名单
| 错误类别 | 触发 | 处置 | 可重放 |
|---|---|---|---|
MALFORMED |
报文非法、原文缺失或缺少该类型必需的业务载荷 | 立即 DEAD |
否 |
PROTOCOL |
载荷存在但整包违反业务协议(运营日冲突、声明数不符) | 立即 DEAD,整包不落地 |
否 |
CODEC_ERROR |
解码能力问题 | FAILED 退避 |
是 |
UNSUPPORTED |
处理器或快照能力未实现 | FAILED 退避,受尝试上限约束 |
是 |
INFRA |
基础设施或执行异常 | FAILED 退避 |
是 |
EXHAUSTED |
尝试次数耗尽 | DEAD;ERROR_CLASS 被覆写为 EXHAUSTED(原始类别不保留,LAST_ERROR 留文本) |
是 |
回填放弃原因:MISSING_ROW(信箱行不存在,确定性结论)、TRANSIENT_DEADLINE(暂时性故障持续到 R 仍未打标)。两者都不写 BACKFILL_AT,都不等于标记已确认;R 之前不放弃。