Files
DongHyeonka d646c2f12f feat(messaging): 브로커 중립 메시징 플랫폼 24개 leaf 추가
messaging-superpowers-package 설계서/계획서 기반 구현.
registry를 19 → 43 leaf로 확장하고 src/messaging 아래 24개 leaf를 등록.

- core-api: M1 publish/consume + M2 batch·delayed·pause-resume
- policy/transport-spi: 재시도 결정, DLQ orchestration, admission control, lifecycle
- kafka·rabbit(Stable): contiguous commit, confirm/return 상관, 배치, 보안 설정
- pulsar·nats(Experimental): 기본 비활성, live 인증 없음을 코드로 기록
- outbox/inbox/claim-check: 트랜잭션 결합, lease, 무결성 검증
- admin: plan → approve → execute를 타입으로 강제
- 문서 9종, infra compose 7종, JMH 벤치마크 3종

검증: 아키텍처 게이트 3종 통과, 24개 leaf 전부 check 통과,
messaging 테스트 604개 통과/0 실패.

미완: 계획서가 요구한 실 브로커 IT 40개 중 7개만 작성.
Rabbit 13 / Outbox 6 / Inbox 4 / NATS·Pulsar·Share 5 / testkit 2 /
starter·admin 3, 그리고 TLS·ACL 2개가 남음.
2026-08-14 14:55:38 +09:00

3.7 KiB

Experimental 정책

Stable과 Experimental의 차이

Stable은 공통 Contract Suite(MessagingAdapterContract)를 변경 없이 통과한 어댑터다. 컴파일되는 어댑터가 아니라, 아래 7가지를 실제로 증명한 어댑터다.

publishesAndConfirms
returnsAmbiguousWhenConfirmIsLost
redeliversWhenSettlementIsLost
preservesMessageIdAcrossRetryAndDlq
keepsSourceUnsettledWhenDlqPublishFails
rejectsOversizedPayloadBeforeTransport
stopsAcceptingNewWorkDuringShutdown

Experimental은 아직 그 증명이 끝나지 않은 어댑터다.

규칙

1. 기본 비활성

messaging.experimental.kafka-share: false
messaging.experimental.pulsar: false
messaging.experimental.nats: false

활성화하지 않으면 validator가 MessagingCapabilityUnavailableException을 던진다. Contract Suite가 아직 증명 중인 어댑터가 누군가의 기본 설정 때문에 load-bearing이 되어서는 안 된다.

2. Stable 모듈이 Experimental 모듈에 의존하지 않는다

Gradle 의존 그래프로 강제된다. messaging-spring-boot-starterallowed_dependenciesmessaging-kafka-share-experimental, messaging-pulsar-experimental, messaging-nats-experimental, messaging-spring-cloud-stream-bridge없다.

verifyCleanArchitectureDependencies가 위반을 빌드 실패로 만든다.

3. Core 계약을 바꾸지 않는다

Experimental 어댑터는 브로커의 차이를 MessagingCapabilities로 표현할 뿐, messaging-core-api의 타입을 바꾸지 않는다.

4. 없는 기능을 광고하지 않는다

어댑터 광고하지 않는 것 이유
Kafka Share Group orderedStream, keyedOrdering, replay, brokerTransaction 경쟁 소비자 + 개별 ack는 partition 순서를 유지할 수 없다
Pulsar brokerTransaction Pulsar에 있지만 플랫폼 Contract Suite로 증명되지 않았다
Pulsar (Shared) keyedOrdering round-robin 분배
NATS JetStream nativeDeadLetter delivery limit 초과 시 terminate할 뿐 라우팅하지 않는다
NATS JetStream keyedOrdering subject 기반 모델에 per-key 순서가 없다

false인 capability를 요구하는 profile은 startup에서 실패한다. 조용히 약화되지 않는다.

5. 명시적 거부

조합 결과
Kafka Share Group + ordering != NONE 거부
Kafka Share Group + pause/resume MessagingCapabilityUnavailableException
Pulsar Shared + ordering=KEY 거부 (Key_Shared 필요)
Pulsar + ordering=DESTINATION 거부
NATS Core + AT_LEAST_ONCE 거부 (JetStream 필요)
NATS ordered consumer + 경쟁 워커 > 1 거부
NATS + ordering=KEY 거부

Spring Cloud Stream bridge

Experimental이 아니라 Optional이다. 위험이 다르다.

Stream은 자체 binder 설정을 소유하므로, binding이 destination profile이 모르는 serializer·error handling·acknowledgement mode를 조용히 획득할 수 있다.

따라서 브리지는 플랫폼 보장에 의존하지 않는 destination에만 허용한다.

ordering scope 선언 → 거부
retry policy 선언   → 거부
dead letter 선언    → 거부

이 셋 중 하나라도 필요하면 native adapter를 쓴다. 거기서만 실제로 강제되기 때문이다.

승격 조건

Experimental → Stable로 올리려면 전부 필요하다.

  1. MessagingAdapterContract 7개 테스트를 변경 없이 통과
  2. 장애 주입(연결 끊김, confirm 유실, settlement 유실) 하에서 통과
  3. 지원 브로커 버전 범위 명시 및 CI 검증
  4. support-matrix.md의 capability 표 갱신
  5. ADR 작성
  6. 기본 활성화 여부에 대한 별도 결정