Files
msgexchange-v2/build.gradle.kts
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

82 lines
3.3 KiB
Kotlin
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.
plugins {
alias(libs.plugins.kotlin.jvm)
alias(libs.plugins.kotlin.ksp) // U01Kotlin 注解处理(无 KSP/kapt 则 Micronaut 不生成 BeanDefinition
alias(libs.plugins.micronaut.application)
}
group = "com.gzzn.omms"
version = "2.0.0-SNAPSHOT"
repositories {
mavenCentral()
}
java {
toolchain {
// Micronaut 5.1 系构件要求 JVM 25+(实测依赖解析结论,修正计划的 JDK 21 口径)
languageVersion = JavaLanguageVersion.of(25)
}
}
kotlin {
jvmToolchain(25)
compilerOptions {
// Keep Jackson XML annotations on both Kotlin constructor parameters and properties.
freeCompilerArgs.add("-Xannotation-default-target=param-property")
}
}
micronaut {
runtime("netty")
testRuntime("junit5")
processing {
incremental(true)
// U01N23):processing.annotations 语义是“注解所在包”的过滤,业务包路径不匹配任何 Micronaut
// 注解,已移除(取默认),避免增量注解处理被错误过滤;注解处理由 kotlin-ksp + micronaut-inject-kotlin 承担。
}
}
dependencies {
// U01Micronaut Kotlin 注解处理器(KSP),生成 @Singleton/@Controller/@ConfigurationProperties 的 BeanDefinition
ksp(libs.micronaut.inject.kotlin)
implementation(libs.bundles.micronaut.runtime)
implementation(libs.micronaut.data.jdbc)
implementation(libs.micronaut.jdbc.hikari)
implementation(libs.micronaut.flyway)
implementation(libs.micronaut.redis.lettuce)
implementation(libs.micronaut.kafka)
implementation(libs.micronaut.discovery.eureka)
// 指标:把管道积压/回填/水位等暴露为 MeterRegistry 指标(版本由 platform BOM 管)
implementation(libs.micronaut.micrometer.core)
implementation(libs.jackson.dataformat.xml)
implementation(libs.jackson.module.kotlin)
implementation(libs.logstash.logback.encoder)
runtimeOnly(libs.mysql.connector.j)
runtimeOnly(libs.postgresql)
runtimeOnly("org.flywaydb:flyway-database-postgresql:12.11.0")
// ACM2-11datasources.reference21 类静态主数据独立 PG 库)驱动 org.postgresql:postgresql
// 随阶段 6 实装加入(当前 reference enabled=false 不加载;版本由 micronaut-platform BOM 钉 ~42.7
runtimeOnly(libs.snakeyaml) // U02:显式版本入 catalog(原无版本号依赖 BOM 覆盖,snakeyaml 不在 micronaut BOM 内)
testImplementation(libs.junit.jupiter)
// U03:配置绑定回归测试的测试库(内存 datasource,冒烟用);
// V2 起 InboxLifecycleJdbcSqlTest 以 H2 的 PostgreSQL 兼容模式直连验证生命周期 SQL 语义
testImplementation(libs.h2)
testImplementation("io.micronaut.test:micronaut-test-junit5")
testImplementation("org.jetbrains.kotlin:kotlin-test")
// P3-AACM2-29):无外部 PG 时 JDBC 集成测试自动起隔离容器;有 MSGX_PG_* 环境变量时不启用
testImplementation("org.testcontainers:postgresql:1.20.4")
}
application {
// Kotlin 顶层 mainApplication.kt)→ JVM 主类为 ApplicationKt
// 不声明则 ./gradlew run 报 "No main class specified"、installDist 产出的启动脚本主类为空。
mainClass.set("com.gzzn.omms.msgexchange.ApplicationKt")
}
tasks.test {
useJUnitPlatform()
}