Files
msgexchange-v2/src/main/resources/application.yml
T
windyboy 1e75a81107 fix(pipeline): 修复取报-处理-回填链路的超时、吞吐、回填与 FIFO 问题
外部调用(ACM2-33)
- 共享 MySQL 与自有 PG 全部补有界超时:驱动 connect/socket 超时 + Hikari 池超时
  (注意 Micronaut 的 Hikari 项是毫秒数,不是 Duration 字面量)
- 删除主泵/毒丸路径的 inline 回填:跨库写不再占用 FIFO 关键路径,回填统一由扫描驱动
- 游标自愈:save() 改为「先 UPDATE、缺行 INSERT」,缺行只记一次 ERROR
- Pump/Dispatcher 外层 catch 补 error 日志与失败计数

投递吞吐(ACM2-34)
- Dispatcher 改批量领取;队头退避未到期或首条发送失败即停止本轮(保持目标内保序)
- 有活不再 sleep;删除不可达的 state==SENT 死条件;markSent 移入分支;
  superseded 清理加轮数上限与空 eventId 保护

回填闭环(ACM2-36,V4)
- MISSING(运行时确认行不存在)立即放弃自动重试并告警;暂时性故障达上限后停止自动重试
- 新增 reopen 人工恢复入口;放弃 ≠ 标记已确认(BACKFILL_AT 仍为空,清除前提不成立)
- 扫描改 (BACKFILL_ATTEMPTS, MSG_ID) 公平轮转并排除放弃行,消除全局回填饥饿
- V4 只加字段与必要索引,不按年龄做任何存量推断

切流播种(ACM2-35,V5)
- cutover-watermark 四模式(min/zero/max/显式 ID),默认不播种、代码不做默认选择
- 升级实例拒绝重新播种(SEEDED_AT 为 NULL ≠ 从未消费);播种与水位同语句落库
- 非法取值由启动自检挡下

错误分类与入口契约(ACM2-37)
- 未知 SCHD 子类型改为 UNSUPPORTED,不再静默当全量日计划合并
- ADFT 运营日冲突改走 ProtocolViolation → DEAD(PROTOCOL)
- 兼容入口 receivedAt 缺失回退到注入 Clock;MessageLifecycleGate 强制注入 + 装配断言
- FIFO:主泵只领取 msgId ≤ W,兼容入口登记的行在水位追平前不被领取

时间源与可观测(ACM2-38 / ACM2-41 阶段 0)
- 仓储/处理器/作业全部经注入 Clock;移除 markTerminal/markBackfilled 的 Instant.now() 默认值
- 退避表档位与 max-attempts 对齐并加启动自检
- Micrometer 7 个 gauge(@Context 急切注册)+ /health 与 /metrics 共用积压快照缓存
- 只读迟到检测:监视被放行的空洞 ID 是否后来真的出现,只计数告警、不补入队

Plane: ACM2-33 ACM2-34 ACM2-35 ACM2-36 ACM2-37 ACM2-38 ACM2-41
Tests: 88 → 120(1 skipped 需真实 PG)
2026-09-11 08:08:35 +08:00

116 lines
6.2 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# =====================================================================
# msgexchange-nextgen 配置(ACM2-12 口径)
# 系统角色:机场 OMMS 上游报文处理中间件(JDBC 轮询共享 CMINMSGS 为主路径;
# compat HTTP POST /cminmsgs/send 为辅助写路径)。
# 口令/端点全部环境变量外置——零入库。
# 存储边界:自有 PostgreSQLdatasources.default,全部内部状态与运营航班权威 FLIGHT_SCHD/SCHD_GEN+
# 共享 MySQL 信箱(mailbox.shared-mysql,仅 DML,不建表)+
# Kafka + Eureka/logstash。权威设计:docs/flight-state.md。
# 键位口径:Micronaut 5.1U03):datasources.* / flyway.datasources.* /
# kafka.producers.<name>.* / eureka.client.*Micronaut 原生键)。
# =====================================================================
msgx:
service-name: msgexchangeapi # 契约冻结;影子实例用 msgexchangeapi-shadow
register-eureka: true # 影子对拍期置 false 或独立服务名
pipeline: # —— ACMA-8 参数表初值(阶段 0 基线校准)——
poll-interval: 1s # KEEP 现役 1s 轮询节奏
claim-batch: 50
max-attempts: 5 # 处理/投递同值
backoff-ms: [1000, 2000, 4000, 8000] # 指数退避;档位数必须 = max-attempts - 1(启动自检)
backoff-cap-ms: 60000
head-deadline: 10m # 队头滞留上界 = 最坏 HOL 时长(毒丸升级)
max-commit-delay: 5m # §5.1 空洞老化:W+1 空洞超过该时延判定为永久(Q2 最大提交时延)
overdue-backfill: 30d # §5.2 超期补写期限 R:≥ 人工重放期限 + 人工处置期限(Q6)
backfill-batch: 100 # 回填扫描单批条数
backfill-max-attempts: 100 # 回填自动重试上限;达上限停止自动重试(可人工恢复),避免占满批次
# 一次性切流播种:默认(注释掉)不播种。min=读现存全部 | zero=从 0 按空洞规则 | max=跳过可见存量 | <id>
# cutover-watermark: min
late-detect-period: 60s # 迟到到达检测(只读,阶段 0):复查被放行的空洞 ID 是否后来真的出现;0=关闭
late-detect-batch: 200 # 每轮最多复查多少个空洞 ID
autostart: false # U07:启动即拉起 Pump/Dispatcher 循环;需真实仓储或 msgx.stubs=true 才开启(dev 见 application-dev.yml
schd:
flush-period: 3s # KEEP 现役推送节律
flush-limit: 500 # 批上限,防积压尖峰
operation-day: # §3.5:SODT + 机场时区 + 切日边界(默认占位 0 点,待业务确认 §10)
zone: Asia/Shanghai
cutoff-hour: 0
history: # §8:历史判定窗口与保留期
cancelled-hours: 48
terminal-hours: 48
deleted-hours: 48
idle-hours: 168
snap-log-retention-days: 90
history-store-enabled: false # 未接通历史存储时 HISTORY_SWEEP 删 0 条(§8.2
micronaut:
application:
name: msgexchange-nextgen
server:
port: 8080
# 管理端点(U03/N32):/env、/beans 默认 sensitive;仅开发/影子环境放开——见 application-dev.yml
# 自有 PostgreSQL:全部内部状态(PIPELINE_LOCK/PROC_STATE/MSG_EVENT/REQ_TRACK/INBOX_CURSOR/
# FLIGHT_SCHD 及明细表/SCHD_SNAP_LOG;迁移 db/migration/V1__flight_state_baseline.sql +
# V2__inbox_lifecycle.sql——V2 起回填意图并入 PROC_STATEBACKFILL_TODO 已下线)。
# 数据层实装前 enabled=falsestub 模式不建连)。
datasources:
default:
enabled: false
url: ${MSGX_PG_URL}
username: ${MSGX_PG_USER}
password: ${MSGX_PG_PASSWORD}
driver-class-name: org.postgresql.Driver
# 有界外部调用:取连接/校验/空闲/寿命都有上限,避免线程无界等待。
# 注意 Micronaut 的 Hikari 配置项是**毫秒数(long**,不是 Duration 字面量。
connection-timeout: 5000
validation-timeout: 3000
idle-timeout: 300000
max-lifetime: 1800000
# 驱动级超时(秒):connectTimeout/socketTimeout,防止网络黑洞挂住调用线程。
data-source-properties:
connectTimeout: 3
socketTimeout: 30
flyway:
datasources:
default:
enabled: ${MSGX_FLYWAY_ENABLED:true}
locations: classpath:db/migration
# 共享 MySQL 信箱(他人系统库,仅 DML:上游外部写 CMINMSGS;本系统 JDBC 轮询读 +
# 处理回填;出站写 COUTMSGS;不建表/schemaACM2-12)。驱动/依赖与信箱适配层
# CminmsgMailbox/OutboxMailbox)随 U05 批次引入。
mailbox:
processed-value: PROCESSED # §5.2 处理标记写入值(Q7:值集与写权限以库方契约为准)
shared-mysql:
enabled: false
url: ${MSGX_MAILBOX_URL}
username: ${MSGX_MAILBOX_USER}
password: ${MSGX_MAILBOX_PASSWORD}
driver-class-name: com.mysql.cj.jdbc.Driver
# 有界外部调用(必填语义,默认即有限):Connector/J 默认 socketTimeout=0 = 无限等待
connect-timeout-ms: 3000
socket-timeout-ms: 30000
pool-connection-timeout-ms: 5000
pool-validation-timeout-ms: 3000
kafka:
bootstrap:
servers: ${MSGX_KAFKA_SERVERS}
producers:
default: # U03/R09Micronaut Kafka 按具名 producer 解析,须有 default 层
# 默认 acks=all + 幂等(现代 Kafka 3.x+);若对接旧版 Broker(如现网 0.10.x/1.x,无 INIT_PRODUCER_ID 协议),
# 经 MSGX_KAFKA_ACKS=1 与 MSGX_KAFKA_IDEMPOTENCE=false 降级兼容。
acks: ${MSGX_KAFKA_ACKS:all}
enable-idempotence: ${MSGX_KAFKA_IDEMPOTENCE:true}
max-in-flight-requests-per-connection: ${MSGX_KAFKA_MAX_IN_FLIGHT:5}
eureka:
client:
registration:
enabled: ${msgx.register-eureka}
default-zone: ${MSGX_EUREKA_URL:http://127.0.0.1:8761/eureka}
# logstash TCP JSON 通道保留(字段兼容现网,ACMA-3 部署前提)。
# U03/N13logback 在 Micronaut 配置体系之外独立初始化,不读本文件——地址见 logback.xml
# 环境变量统一前缀 MSGX_LOGSTASH_HOST / MSGX_LOGSTASH_PORT(不要再在此处定义 logstash.* 死键)。