배경 및 목표

프로그래머스와 일부 플로우에선 동기 방식으로 연동하고 있어, 외부 플랫폼 장애 발생 시 자사 서비스에 영향을 주었습니다. 또한 신규 채용 플랫폼을 추가할 때마다 기존 코드를 수정해야 했습니다.

graph LR
    subgraph sync["❌ 동기 연동"]
        S["자사 서비스"] -->|"동기 호출"| E["잡플래닛"]
        E -->|"장애"| S
    end

목표

  • 외부 플랫폼 장애가 자사 서비스로 전파되지 않도록 연동을 격리한다.
  • 신규 플랫폼을 기존 코드 수정 없이 토픽 구독만으로 확장한다.

해결 방법과 해결 후보군

후보군 비교

방식설명한계
동기 호출 유지외부 API 직접 호출외부 장애 전파, 신규 플랫폼 추가 시 코드 수정
동기 + 재시도 래핑try-catch 재시도장애 시 응답 지연 여전, 결합 유지
이벤트 드리븐 (채택)Kafka 이벤트 발행장애 격리, 토픽 구독만으로 플랫폼 확장

1. Kafka 이벤트 드리븐 아키텍처 전환

동기 호출을 제거하고, 자사 서비스는 Kafka 토픽에 이벤트만 발행하는 구조로 변경했습니다. 외부 플랫폼과의 직접 의존이 사라지므로, 외부 장애가 자사 서비스에 전파되지 않습니다.

// 자사 서비스: 이벤트만 발행
@TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT)
fun onEntityCreated(event: EntityCreatedEvent) {
    kafkaTemplate.send("event.domain.created", event.toMessage())
}

2. 플랫폼별 컨슈머 그룹 분리

각 외부 플랫폼에 독립적인 컨슈머 그룹을 부여했습니다. 잡플래닛 컨슈머에 문제가 생겨도 다른 플랫폼 컨슈머는 정상 동작합니다. 신규 플랫폼 추가 시에는 새 컨슈머 그룹이 토픽을 구독하기만 하면 되므로, 기존 코드 수정이 불필요합니다.

graph TB
    S["자사 서비스"] -->|"이벤트 발행"| K["Kafka Topic"]
    K -->|"컨슈머 그룹 A"| P1["잡플래닛"]
    K -->|"컨슈머 그룹 B"| P2["신규 플랫폼"]
    K -->|"컨슈머 그룹 C"| P3["..."]

3. 재시도 API

네트워크 순단 등으로 일부 메시지 처리가 실패할 수 있으므로, 실패 건에 대한 재처리 API를 제공했습니다. 컨슈머 측에서 실패를 기록하고, 운영자가 재시도를 트리거할 수 있습니다.

이 이벤트 드리븐 연동 패턴이 이후 ORP, 프로그래머스 등 모든 외부 연동의 표준이 되었습니다.


결과

지표결과
장애 격리100%
신규 플랫폼 확장토픽 구독만으로
부분 실패허용 + 재시도

모니터링

  • 플랫폼별 컨슈머 그룹의 랙·실패율과 재시도 API 호출 건수를 관측한다.
  • 외부 장애 발생 시 자사 서비스 영향도(격리 여부)를 관측한다.