[문제 해결] 분산 서버간 이벤트 교환 시스템 구축기

neo-the-cow·2024년 5월 25일

문제 해결

목록 보기
3/4
post-thumbnail

실시간 다중 채팅 서비스 프로젝트를 진행하며 겪었던 문제와 해결과정을 기록합니다.

1. 문제 상황과 원인 분석

  • REST API에서 처리한 채팅 방에 입장하면 채팅 방 인원들에 이벤트 메시지와 새로운 참여자 정보를 전송해야 했습니다.
  • 하지만 REST API와 웹 소켓 서버가 분산된 환경에서 REST API 서버가 처리한 내용을 웹 소켓 서버는 알 수 없습니다.
  • 채팅 방 참여 이벤트가 발생하면 DB에는 참여자 정보 레코드가 생성되고 API를 호출한 클라이언트에 응답이 전송됩니다.
  • 하지만 같은 채팅 방에 참여중인 다른 클라이언트에는 정보가 전달되지 못하고 결국 참여 한 클라이언트가 웹 소켓 서버로 다시한번 요청을 보내야 합니다.

2. 문제 해결

2.1 해결 방안 1 - 이벤트 직접 발행

  • 앞서 메시지 전송 문제로 도입한 이벤트 브로커에 토픽을 생성하고 직접 이벤트를 발행할 수 있습니다.
  • 직접 이벤트를 발행하는 과정을 의사코드로 나타내면 다음과 같습니다.
public class ChatEventProducer {
	...
	@Async
	@Override
	public void produceEnter(이벤트_모델 model) {
		... 카프카 이벤트 발행 ...
	}
	...
}

---

public class SimpleChatRoomService {
	...
	@Override
	@Transactional
	public Room enterRoom(식별자_자료형 roomId, 요청_모델 request) {
		1. 락 획득
		2. 채팅 방 입장 처리
		3. if 입장 성공 then chatEventProducer.produceEnter(new 이벤트_모델());
	}
	...
}
  • @Async 어노테이션으로 이벤트 발행 과정을 비동기 처리합니다. 이벤트 발행을 정상적으로 수행했는지 확인하는 절차를 추가할 수 있습니다.

비즈니스 로직에서 수행하는 책임 증가 문제

  • 트랜잭션 처리와 이벤트 발행 로직이 합쳐져 복잡도가 증가합니다 이벤트 발행 실패에 따른 롤백 처리문제가 발생할 수 있고 여러 동작을 한꺼번에 처리하기 때문에 유지보수성을 저해합니다.

2.2 해결 방안 2 - CDC 도구 Debezium(Kafka Connect) 도입

  • v0.0.1에서 CQRS패턴을 위해 적용한 Debezium을 도입할 수 있습니다.
  • Debezium은 트랜잭션 로그를 읽고 Kafka에 이벤트를 발행하는 CDC(Change Data Capture)도구 입니다.
  • 데이터의 변경사항을 실시간으로 감지하고 이벤트를 발행하기 때문에 비즈니스 로직과 이벤트 발행 책임을 분리할 수 있습니다.

  • Kafka로 발행된 이벤트는 웹 소켓 서버에서 Consume 되며 입/퇴장 이벤트에 필요한 로직을 수행합니다.

3. 적용한 방법

  • CDC도구 Debezium을 도입했습니다.
  • REST API에서 이벤트 발행이 필요한 처리에서 비즈니스 로직과 이벤트 발행 로직을 분리해 책임 소재를 명확하게 하고 문제상황 시 디버깅 용이성을 기대할 수 있습니다.
  • REST API서버에서 장애가 발생하더라도 장애사항의 전파를 막을 수 있습니다.
  • 관련 포스팅: 로컬환경 Kafka 클러스터 구축기
profile
Hi. I'm Neo

0개의 댓글