자바 스프링 MSA 환경에서 카프카를 이용해 주문 취소 기능을 구현하며 발생한 문제와 해결 방법에 대해 작성한다.
소개
구현하고자 하는 바는 다음과 같다.
- 사용자는 자신의 주문에 대해 '주문 취소'를 요청한다.
- 주문 서비스는 주문 취소 작업 처리 후 카프카에 '주문 취소 토픽'에 이벤트를 발행한다.
- 이때 주문 취소 토픽은 하나의 파티션으로 구성되어 있다.
- 상품 서비스와 결제 서비스는 '주문 취소 토픽'에서 이벤트를 소비해서 작업을 처리한다.
문제
주문 서비스에서 주문 상태를 취소로 변경하고 주문 취소 이벤트를 카프카 주문 취소 토픽에 발행해 상품 서비스와 결제 서비스에서 해당 주문 취소 토픽을 구독하고 이벤트를 소비하려 했다.
그러나 테스트 결과는 달랐다.
이벤트가 제대로 발행되는 것은 확인했으나, 두 서비스 모두에서 이벤트를 소비하는 것이 아니라 하나의 서비스에서만 이벤트를 소비하고 작업이 이루어졌다.
원인
이 문제의 원인은 카프카에서 동일한 컨슈머 그룹을 사용할 경우 하나의 파티션에서는 하나의 컨슈머만 메시지를 소비할 수 있기 때문이다.
즉, 상품 서비스와 결제 서비스가 동일한 컨슈머 그룹을 사용하면서 하나의 토픽에서 메시지를 소비하려 했기 때문에, 두 서비스 중 하나만 메시지를 소비하게 되었다.
구현 과정에서 상품 서비스, 주문 서비스, 결제 서비스 모두 다음과 같이 컨슈머 설정을 해주었다.
KafkaConsumerConfig
private Map<String, Object> getConsumerConfigurations(JsonDeserializer<?> deserializer) {
Map<String, Object> consumerConfigurations = new HashMap<>();
consumerConfigurations.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, kafkaProperties.getServer());
consumerConfigurations.put(ConsumerConfig.GROUP_ID_CONFIG, kafkaProperties.getGroupId());
consumerConfigurations.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class);
consumerConfigurations.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, deserializer.getClass());
consumerConfigurations.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "latest");
return consumerConfigurations;
}
- 상품, 주문, 결제 서비스 모두 ConsumerConfig.GROUP_ID_CONFIG의 값으로 동일한 Group ID를 적용하였다.
해결
나의 경우 이 문제를 해결하기 위해 각 서비스마다 별도의 컨슈머 그룹 ID를 지정하였고, 이를 통해 서비스 모두 주문 취소 이벤트를 제대로 소비하게 되었다.
결론
이처럼 카프카를 이용해 여러 서비스에서 동일한 토픽의 메시지를 소비하려 할 때는 컨슈머 그룹 설정에 주의가 필요하다.
각 서비스가 독립적으로 메시지를 소비하려면 각 서비스에 대해 별도의 컨슈머 그룹을 설정해주는 것이 중요하다!!
'기술 블로그 > MiriMiri' 카테고리의 다른 글
비동기 통신을 통한 마이페이지 성능 개선 (0) | 2024.05.20 |
---|---|
MSA 환경에서 Kafka 이벤트 기반 주문 처리와 트랜잭션 관리 (0) | 2024.05.14 |
Redis 복제(Replication)를 사용한 상품 재고 관리 (0) | 2024.05.14 |
상품 주문 성능 개선 과정 (0) | 2024.05.10 |
Redis를 사용한 MSA 환경에서 상품 재고 관리 (0) | 2024.05.05 |