728x90
1. 도입
바인드 프로젝트에서는 주요 도메인 간 통신을 단순 HTTP 호출이 아닌 Kafka 기반 이벤트 구조로 풀고 있다.
특히 메시지 전달의 신뢰성과 트랜잭션 일관성을 위해 Outbox 패턴을 직접 설계·구현했고,
Kafka와의 연결을 통해 비동기 메시징 인프라를 통합적으로 구성했다.
이번 글에서는 우리가 Auth 모듈을 이 인프라 위에 어떻게 올려
이메일 전송 및 회원 탈퇴 연동 로직을 자연스럽게 확장했는지를 소개한다.
2. 목표
| 목표 | 설명 |
|---|---|
| ✅ 인증 로직과 외부 서비스 분리 | Auth는 이벤트만 발행, 처리는 외부에서 담당 |
| ✅ Outbox 기반 신뢰성 보장 | 메시지 전송을 트랜잭션에 통합 |
| ✅ Kafka를 통한 비동기 연결 | 느슨한 결합 구조 유지 |
| ✅ 확장성 있는 이벤트 모델 | 다양한 도메인이 같은 이벤트를 구독 가능하도록 설계 |
3. 고려한 설계사항
| 항목 | 설계 방향 | 이유 |
|---|---|---|
| 메시지 발행 시점 | 도메인 트랜잭션 내에서 Outbox 테이블에 기록 | DB와 메시지 일관성 확보 (원자성) |
| 메시지 발행 방법 | OutboxEventPublisher.publish(event) |
기존 구조 재사용 |
| Kafka 연동 | KafkaProducerConfig 기반 자동 전송 | 이미 검증된 메시징 인프라 |
| 메시지 스키마 | EmailSendEvent, UserDeletedEvent |
명확한 역할 분리와 확장 고려 |
4. 구현 설명
4.1 Outbox 발행 구조 (기존 재활용)
eventPublisher.publish(new EmailSendEvent(
user.getEmail(), "인증 메일", "가입을 환영합니다!")
);
eventPublisher.publish(new UserDeletedEvent(user.getId(), user.getEmail()));
EmailSendEvent,UserDeletedEvent는@JsonTypeInfo기반 직렬화 구조를 따름- 이벤트는 Outbox 테이블에 저장되고, 별도 메시지 중계기가 Kafka에 전송
4.2 이벤트 클래스 예시
public class EmailSendEvent extends AbstractOutboxEvent {
private String to;
private String subject;
private String content;
public EmailSendEvent(String to, String subject, String content) {
this.to = to;
this.subject = subject;
this.content = content;
}
}
4.3 Kafka Topic 구성
| Topic 이름 | 이벤트 타입 |
|---|---|
email.send |
EmailSendEvent |
user.deleted |
UserDeletedEvent |
→ 이벤트 타입 별로 Topic 분리하여 소비자 확장 용이
5. 테스트 전략
- 기존 Outbox 구조의 통합 테스트 재활용
- 이메일/유저삭제용 KafkaConsumer mock을 활용한 end-to-end 흐름 검증
- 이벤트 누락/중복 전송 검증 포함
6. 느낌점
느낀 점
- 이벤트 기반 아키텍처를 Auth 모듈까지 확장하면서 느낀 가장 큰 이점은 코드 일관성과 재사용성이었다.
- Outbox 패턴은 단순히 기술 선택이 아니라, 전체 서비스의 일관된 메시징 철학을 구현하는 방식이라는 걸 다시 확인할 수 있었다.
확장 방향
| 항목 | 설명 |
|---|---|
| ✅ 멀티 이벤트 구독 | 같은 이벤트를 알림/로그/보안 모듈 등도 구독 |
| ✅ 메시지 추적 시스템 도입 | Outbox → Kafka → Consumer 전체 추적 체계 도입 예정 |
| ✅ 보안 알림 이벤트 추가 | 로그인 실패, 권한 변경 등의 이벤트화 |
| ✅ 인증 성공 로그 이벤트 | 감사 목적의 Kafka 전송 확장 계획 |
마치며
단순히 이메일을 보내거나 유저 삭제를 처리하는 작업처럼 보일 수 있지만,
우리는 이를 통해 트랜잭션 신뢰성, 도메인 분리, 확장 가능성, 운영 가시성까지 확보할 수 있었다.
Kafka와 Outbox를 도입한 건 단지 기술 스택의 선택이 아니라,
지속 가능한 마이크로서비스 설계를 위한 전략적 기반이었다.
728x90
'BindProject' 카테고리의 다른 글
| [회고] Refresh Token 전략과 Redis 기반 설계, 그리고 트러블슈팅 회고 (1) | 2025.06.20 |
|---|---|
| [Backend] Auth모듈: JWT 로그아웃 설계와 Redis 기반 블랙리스트 구현 (1) | 2025.06.20 |
| [Backend]Auth모듈: 인증 시스템 설계와 구현 -FIN-!! (0) | 2025.06.19 |
| [Backend] Auth모듈 : 유저 탈퇴 처리 (1) | 2025.06.19 |
| [Backend] Auth모듈 : 역할(Role) 부여 기능 구현기 (0) | 2025.06.19 |