문제상황
- 서버리스 아키텍처(lamda)의 콜드 스타트 문제로 인해 번쩍 API 응답속도가 약 5초 정도 소요됨.
- 알림 서버 API 응답 이후, 개설 API 응답을 실행하는 구조라 비즈니스 로직에 영향을 미치는 상황
원하는 기능
<aside>
💡
“모임 생성과 알림 발송을 제대로 분리”하면서도, “DB가 커밋된 뒤에만 알림을 보내기”
</aside>
도입과정
1. 개설 API, 알림 API 분리 (서버에서 분리 X, 클라이언트/프론트 단에서 2번 호출)
- 장점
- 서버측 입장에서 두 로직(모임 개설, 알림 발송)이 완전히 분리되며, 구현이 간단
- 단점
- 클라이언트 측에서 2번 호출(모임 개설 → 알림 발송)해야 하므로, API 사용성이 떨어짐
- 모임 개설이 성공했어도, 클라이언트가 실수로 알림 API 호출을 빼먹거나 실패하면 알림 발송 누락
- 운영 관점에서 “모임 개설 시 자동 알림 발송”이 확실히 보장되지 않음
- 모임 생성 → 알림 발송이 동일한 트랜잭션 문맥을 공유하지 못함
- 보안적으로 알림 API를 제3의 인물이 호출할 수 있는 여지를 줌
- 결론
- 장점보다 단점이 많기 때문에 도입 x
- 개발/배포가 매우 간단하고, API 스펙을 정확히 지킬 수 있는 클라이언트가 있을 때는 괜찮지만, “모임 개설과 동시에 자동 알림”을 백엔드에서 책임지고 처리하는게 맞다고 생각
2. Spring 비동기(@Async) 방식
- 장점
- 개발이 매우 간단 (메서드에 @Async만 붙이면 됨)
- DB 저장(메인 로직)과 알림 발송이 분리되어, 모임 개설 API 응답 시간 최소화
- 별도 인프라(메시지 큐 등) 없이도 가능
- 단점
- @Async는 메서드를 호출하는 순간 별도 스레드가 실행되므로, 트랜잭션 커밋 전이라도 이미 알림 요청이 갈 수 있음
- 서버 프로세스가 죽거나 재시작되면, 진행 중인 @Async 작업이 사라질 수 있음(재시도 X)
- “DB 커밋이 보장된 후”라는 시점 제어가 필요하면, 추가 로직/코드가 필요
- 결론
- 단순하게 “API 응답과 알림 전송을 분리”하는 목적이라면 가장 빠른 방법, 그러나 “DB가 확실히 커밋된 뒤 알림을 보낼 것”이 중요한 경우, 롤백 시점에서 맞지 않을 수 있음.
3. Spring EventListener + Async
- 장점
- 도메인 이벤트를 사용하면, “모임 생성”이라는 이벤트에 대해 다른 리스너를 쉽게 붙일 수 있어 확장성이 좋음
- 알림 로직을 “모임 생성” 도메인 로직과 느슨하게 연결(= 이벤트)할 수 있어 코드 가독성 향상
- 여전히 @Async를 통해 메인 응답과 분리