비즈니스 로직과 알림 발송의 '완벽한 결별'을 통해 데이터 정합성과 개발 생산성을 동시에 잡은 기술 전환기
올리브영의 급성장하는 비즈니스 요구사항을 감당하기 위해, 파편화된 레거시 알림 시스템을 Kafka 기반 MSA 환경으로 전환한 과정을 다룹니다. 신입 엔지니어의 시선에서 겪은 기술적 제약 사항과 이를 해결하기 위한 트랜잭션 동기화 기법, 그리고 책임 분리를 통한 아키텍처 개선 과정을 상세히 공유합니다. 단순한 기능 구현을 넘어 시스템 설계의 본질과 안정적인 데이터 흐름을 고민하는 개발자들에게 실질적인 인사이트를 제공합니다.
레거시 시스템을 점진적으로 MSA로 전환하고 있거나, 비즈니스 로직과 외부 연동 로직 사이의 데이터 정합성 문제로 고민하는 백엔드 엔지니어에게 적극 추천합니다. 특히 Spring 프레임워크 버전 제약으로 인해 최신 기능을 사용하기 어려운 환경에서 트랜잭션 커밋 시점을 제어하는 실용적인 대안을 제시합니다.
기존 알림톡 시스템은 로직이 비즈니스 코드에 산재해 있어 수정이 어렵고, 데이터 조회 기준이 서비스마다 달라 일관성이 부족했습니다. 특히 비즈니스 로직과 발송 처리가 강하게 결합되어 있어, 발송 후 로직 오류 발생 시 데이터 상태와 안내 내용이 불일치하는 안정성 문제가 존재했습니다.
Spring의 TransactionSynchronizationManager를 활용하여 비즈니스 트랜잭션 커밋 이후에만 Kafka 메시지를 발행하도록 콜백 구조를 구현했습니다. 이를 통해 레거시 시스템은 발송 시점만 결정하고, 모던 아키텍처 기반의 컨슈머가 메시지를 소비하여 배송 유형별 공통 쿼리 조회 및 발송 처리를 전담하도록 역할을 분리했습니다.
발송 로직이 모던 시스템으로 일원화되면서 새로운 알림톡 추가 시 템플릿과 시점만 등록하면 되는 간편한 구조가 완성되었습니다. 또한 데이터 상태와 알림 발송 간의 정합성이 확보되었으며, 산재해 있던 데이터 조회 기준을 통합하여 시스템의 일관성과 유지보수성이 크게 향상되었습니다.
Trade-off
초기에는 @TransactionalEventListener를 도입하려 했으나 레거시 환경의 프레임워크 버전 충돌 및 의존성 문제로 인해 TransactionSynchronizationManager를 활용한 차선책을 선택했습니다. 본문에 구체적인 한계는 없으나, 현재 구조는 메시지 발행 실패 시 로그 기반 재처리에 의존하므로 트랜잭션 아웃박스 패턴(Outbox Pattern) 대비 발행 보장 측면에서 상대적으로 완결성이 낮을 수 있습니다.
Spring에서 트랜잭션의 생명주기에 맞춰 특정 작업을 동기화하거나 등록된 리소스를 관리하는 중앙 관리 클래스입니다.
메시지 브로커인 Kafka를 중심으로 시스템 간 이벤트를 주고받아 결합도를 낮추는 아키텍처 스타일입니다.
프로그램의 각 부분이 서로 겹치지 않는 별개의 관심사를 가지도록 기능을 분리하는 설계 원칙입니다.



