项目概述
Spring Boot Integration Lab 展示了一个用于调用不可靠外部合作方 API 的精简履约网关。其重点不只是常规请求与响应处理,还包括超时、重试、合作方故障和客户端重复请求所留下的不确定状态。这是一个使用模拟合作方的独立工程演示,并非客户项目或生产部署。
工程挑战
写入超时并不能证明合作方没有处理请求。合作方可能已经提交操作,只是响应丢失或延迟。没有去重机制的重试可能重复产生影响;返回确定的失败也可能不准确。因此,网关需要持久化请求归属、明确的状态语义、合作方幂等契约,以及协调不确定结果的方式。
架构
网关负责其公开 API、基于 MySQL 的履约与幂等状态、出站 HTTP 客户端、弹性策略和指标。独立的模拟合作方服务通过 HTTP 与网关通信,并模拟可重复的故障。网关与合作方不共享 MySQL。Prometheus 抓取可通过 Compose 配置启用。对于提交后超时的场景,网关可按请求标识查询合作方;若确认已完成则记录结果,否则保留 UNKNOWN 状态,而不是将不确定性视为业务失败。
关键设计决策
- 网络调用之前先持久化幂等归属。数据库状态先确定哪个请求拥有该键;事务不会在等待合作方响应期间保持打开。
- 采用保守的响应语义。合作方写入结果不明确时可以保留为 202 UNKNOWN,网关不会自动将其归类为失败。
- 仅对选定的暂时性故障重试。超时、重试策略、熔断和限流均显式配置,并向模拟合作方传递稳定的幂等键。
- 网关与合作方保持独立。HTTP 是集成边界,避免共享表或代码掩盖对外部系统的假设。
- 不承诺恰好一次执行。网关幂等性并不等于分布式恰好一次;要避免跨边界重复影响,需要合作方去重或其他合作方支持的契约。
实现与验证
仓库包含独立的 integration-gateway 和 mock-partner Spring 服务、MySQL 架构与 Compose 配置、弹性和可观测性代码,以及确定性的故障场景。集成测试使用 Testcontainers MySQL 和 WireMock。README 记录了正常履约、重复请求、键冲突、并发重复、重试分类、模糊超时协调、关联 ID 和指标暴露等测试覆盖。
所检查主分支提交对应的 GitHub Actions 验证工作流最近一次可见运行已成功。README 也记录了本地 k6 观察结果,但这些是单次本地演示并附有明确说明;本案例没有将其描述为容量基准或生产 SLO。
局限与后续工作
合作方模拟器使用内存去重。限流器仅在进程内生效,无法在多个网关实例间实施共享配额。系统不包含身份验证、告警系统或后台协调工作进程。生产使用还需要根据合作方契约、部署拓扑、身份体系和运维要求进行威胁建模并配置相应控制措施。
项目资源
验证说明
- 所检查主分支提交对应的 GitHub Actions 验证工作流最近一次可见运行已成功。
- README 记录了 Spring Boot 测试、Testcontainers MySQL、WireMock 和 Docker Compose 冒烟测试任务。
- 文档覆盖重复请求、幂等冲突、并发、重试分类、超时协调、关联信息传播和指标。
局限
- 合作方服务是确定性的模拟服务,其去重状态保存在内存中。
- 限流器仅在单进程内生效;多个网关副本之间的共享配额需要协调机制。
- 不包含身份验证、生产告警或后台协调工作进程。