feat: 공식 문서 근거자료, 브랜치 기능 문서 작성
This commit is contained in:
@@ -0,0 +1,80 @@
|
||||
---
|
||||
title: official-doc / Spring for Apache Kafka — Non-Blocking Retry Topic Pattern (Ordering Loss)
|
||||
source_type: official-doc
|
||||
url: https://docs.spring.io/spring-kafka/reference/retrytopic/how-the-pattern-works.html
|
||||
archive_url:
|
||||
related_branches: [feature-kafka-consumer-inbox-contract]
|
||||
related_projects: [ca-skeleton]
|
||||
tags: [official-doc, ca-skeleton, messaging, kafka, retry-policy, dead-letter-queue]
|
||||
created: 2026-07-28
|
||||
---
|
||||
|
||||
# official-doc / Spring for Apache Kafka — Non-Blocking Retry Topic Pattern (Ordering Loss)
|
||||
|
||||
> Layer: `raw/` — 외부 자료(공식 문서)의 **원문 발췌·출처 기록**.
|
||||
> 문서 버전: Spring for Apache Kafka reference **4.1.0** (페이지 상단 버전 표기 기준, 2026-07-28 확인).
|
||||
|
||||
## Parent / 활용 branch
|
||||
|
||||
| Branch | 이 자료가 정당화하는 결정 |
|
||||
|---|---|
|
||||
| [[raw/branch-notes/feature-kafka-consumer-inbox-contract]] | ca-skeleton consumer 재시도 전략 선택 — non-blocking retry topic 체인이 파티션 정체를 피하는 대신 Kafka 의 순서 보장을 잃는다는 공식 자인이, per-aggregate(파티션 키) 순서 보장을 유지해야 하는 계약에서 이 대안을 언제 배제/채택할지의 선택 조건 근거 |
|
||||
|
||||
## 출처
|
||||
|
||||
- 원본 URL: https://docs.spring.io/spring-kafka/reference/retrytopic/how-the-pattern-works.html
|
||||
- 아카이브 URL: (미제공)
|
||||
- 저자 / 조직: Spring team (Broadcom / VMware Tanzu — Spring for Apache Kafka reference)
|
||||
- 발행일: (reference 페이지 자체에 발행일 미표기 — 버전 4.1.0 기준 문서)
|
||||
- 마지막 확인일: 2026-07-28
|
||||
|
||||
## 왜 저장했는지
|
||||
|
||||
ca-skeleton 의 `adapter:inbound:messaging-kafka` consumer 가 non-blocking retry topic 체인(retry topic + DLT)을 재시도 전략으로 채택할지 결정하려면, 이 패턴이 **Kafka 의 순서 보장을 잃는다**는 공식 자인을 근거로 per-aggregate 순서 보장 요구가 있는 leaf 에서 배제 조건을 판단해야 한다. 이 raw 문서는 그 배제/채택 판단의 1차 근거다.
|
||||
|
||||
## 핵심 인용
|
||||
|
||||
> [§How the Pattern Works] "If message processing fails, the message is forwarded to a retry topic with a back off timestamp."
|
||||
|
||||
> [§How the Pattern Works] "The retry topic consumer then checks the timestamp and if it’s not due it pauses the consumption for that topic’s partition."
|
||||
|
||||
> [§How the Pattern Works] "If the message processing fails again the message will be forwarded to the next retry topic, and the pattern is repeated until a successful processing occurs, or the attempts are exhausted, and the message is sent to the Dead Letter Topic (if configured)."
|
||||
|
||||
> [§How the Pattern Works] "To illustrate, if you have a "main-topic" topic, and want to set up non-blocking retry with an exponential backoff of 1000ms with a multiplier of 2 and 4 max attempts, it will create the main-topic-retry-1000, main-topic-retry-2000, main-topic-retry-4000 and main-topic-dlt topics and configure the respective consumers."
|
||||
|
||||
> [§How the Pattern Works] "By using this strategy you lose Kafka’s ordering guarantees for that topic."
|
||||
|
||||
> 참고: 원문은 straight apostrophe(`'`)가 아니라 curly apostrophe(U+2019, `’`)를 사용한다 (`it’s`, `topic’s`, `Kafka’s`). 위 인용은 원문 문자 그대로(U+2019) 보존했으며, self-grep 검증도 동일 문자로 수행했다 — 아래 검증 로그 참조.
|
||||
|
||||
## Claims Extracted
|
||||
|
||||
| Claim ID | Claim (이 자료가 직접 말하는 것) | Evidence quote | Strength | Applies to | Does not prove |
|
||||
|---|---|---|---|---|---|
|
||||
| SPRK-RETRYTOPIC-C1 | non-blocking retry topic 패턴은 처리 실패 메시지를 back-off timestamp 와 함께 별도 재시도 토픽으로 포워딩하고, 재시도 토픽 컨슈머는 그 timestamp 가 도래하기 전까지 **해당 토픽 파티션의 소비 자체를 일시 중지**한다 | [§How the Pattern Works] "If message processing fails, the message is forwarded to a retry topic with a back off timestamp." + "The retry topic consumer then checks the timestamp and if it’s not due it pauses the consumption for that topic’s partition." | `official-vendor-doc` | Spring for Apache Kafka 의 `@RetryableTopic`/`RetryTopicConfiguration` non-blocking retry 기능 (reference 4.1.0) | 이 메커니즘이 raw Kafka client(Spring 미사용) 컨슈머에도 그대로 적용된다는 것 |
|
||||
| SPRK-RETRYTOPIC-C2 | 재시도가 반복 실패하면 다음 재시도 토픽으로 계속 포워딩되다가, 시도 횟수 소진 시(그리고 DLT 가 설정된 경우) Dead Letter Topic 으로 전송된다 | [§How the Pattern Works] "If the message processing fails again the message will be forwarded to the next retry topic, and the pattern is repeated until a successful processing occurs, or the attempts are exhausted, and the message is sent to the Dead Letter Topic (if configured)." | `official-vendor-doc` | 동일 non-blocking retry 기능의 종료 조건 | DLT 전송이 항상 강제된다는 것 — 원문의 "(if configured)"는 DLT 가 선택 설정임을 명시 |
|
||||
| SPRK-RETRYTOPIC-C3 | 이 전략(non-blocking retry topic 체인)을 사용하면 **해당 토픽의 Kafka 순서 보장을 잃는다** — 공식 문서가 직접 자인하는 trade-off | [§How the Pattern Works] "By using this strategy you lose Kafka’s ordering guarantees for that topic." | `official-vendor-doc` | non-blocking retry topic 전략을 채택하는 임의 토픽 — per-aggregate(파티션 키) 순서 보장이 필요한 leaf 에서 이 전략을 배제/채택할지 판단하는 결정적 근거 | blocking retry 가 전반적으로 우월하다는 것은 아님 — 순서 손실의 정량적 영향(예: 얼마나 자주, 어느 범위까지)은 명시하지 않으며, 파티션 키 설계로 순서 손실을 완화할 수 있는지도 이 문장만으로는 증명 못 함 |
|
||||
| SPRK-RETRYTOPIC-C4 | 예시 설정(1000ms 백오프, multiplier 2, 최대 4회 시도)에서 프레임워크는 `<topic>-retry-<backoffMs>` 형태의 재시도 토픽들과 `<topic>-dlt` 토픽을 **자동 생성**하고 리스너까지 구성한다 | [§How the Pattern Works] "it will create the main-topic-retry-1000, main-topic-retry-2000, main-topic-retry-4000 and main-topic-dlt topics and configure the respective consumers." | `official-vendor-doc` | 기본(커스터마이징 없는) 토픽 명명 및 자동 생성 동작의 예시 | 이 예시가 보여주는 것은 특정 백오프 설정(1000ms×2, 4회)에서의 네이밍이며, `-retry`/`-dlt` 단독 접미사가 모든 설정에서 고정된 기본값이라는 일반 규칙은 별도 "Topic Naming" reference 페이지 소관 — 이 URL(1 dispatch = 1 URL 원칙) 로는 확인하지 않음, **미발견** |
|
||||
|
||||
## Usage Boundaries
|
||||
|
||||
- 이 자료가 직접 증명하는 것:
|
||||
- `SPRK-RETRYTOPIC-C1`, `SPRK-RETRYTOPIC-C2`: non-blocking retry topic 패턴의 동작 메커니즘(timestamp 기반 pause/resume, 시도 소진 시 DLT)
|
||||
- `SPRK-RETRYTOPIC-C3`: 이 전략이 해당 토픽의 Kafka 순서 보장을 깨뜨린다는 공식 자인 — per-aggregate 순서 보장이 필요한 consumer 설계에서 이 대안을 배제할지 판단하는 결정적 근거
|
||||
- `SPRK-RETRYTOPIC-C4`: 특정 백오프 설정 예시에서의 토픽 자동 생성/명명 동작
|
||||
- 이 자료가 증명하지 않는 것:
|
||||
- blocking retry(동일 파티션 내 backoff) 전략이 순서를 보존하면서도 처리량/지연 측면에서 더 우월하다는 것 — 이 문서는 trade-off 의 한쪽(순서 손실)만 자인할 뿐 대안 비교를 제공하지 않음
|
||||
- `-retry`/`-dlt` 접미사가 모든 backoff 설정에서 고정된 기본값이라는 일반 규칙 (Topic Naming 별도 페이지 소관, 이 dispatch 범위 밖)
|
||||
- AckMode·`seekAfterError` 관련 문장(원문에 존재하나 본 raw 문서는 ca-skeleton 결정 근거로 요청된 순서 손실/패턴 동작/명명에 집중해 별도 Claim 화하지 않음 — 필요 시 후속 raw 문서로 분리)
|
||||
- 내 프로젝트에 적용하려면 추가 확인이 필요한 것:
|
||||
- ca-skeleton `adapter:inbound:messaging-kafka` 의 실제 파티션 키 설계(예: aggregate id 기반)가 이 순서 손실 trade-off 를 어느 leaf 에서 감수 가능한지/불가능한지 branch-local 결정(D-row)으로 명시 필요
|
||||
- 이 전략을 채택할 경우 `InboxStorePort` 멱등 계약과의 상호작용(재시도 토픽에서 재처리되는 메시지의 멱등 판정) 검증 필요 — sibling branch `feature-idempotency-ownership-protocol-contract` 소관
|
||||
|
||||
## 메모
|
||||
|
||||
- 인용 해석 후보(미검증): 순서 손실은 "해당 토픽" 단위로 발생하므로, 만약 재시도 토픽을 원본과 동일 파티션 키로 구성한다면 같은 key 의 메시지끼리는 재시도 토픽 내에서 여전히 순서가 섞일 수 있음 — 이 문서만으로는 파티션 키 유지 여부에 따른 완화 가능성을 확인할 수 없음 (검증 필요)
|
||||
- 추가로 봐야 할 동일 출처 페이지: `retrytopic/topic-naming.html`(기본 접미사 커스터마이징 규칙), `retrytopic/features.html`(추가 옵션), `retrytopic/dlt-strategies.html`(DLT 처리 전략) — 각각 별도 dispatch 로 수집
|
||||
|
||||
## Related
|
||||
|
||||
- 같은 주제 다른 official-doc / company-tech-blog: (아직 없음 — Kafka 공식 consumer configs·rebalance 문서는 `feature-kafka-consumer-inbox-contract` 의 "추가 수집 필요" 항목으로 남아 있음)
|
||||
- 이 자료를 인용한 wiki 요약: (생성 시 링크)
|
||||
Reference in New Issue
Block a user