해결된 질문
작성
·
1.4K
2
안녕하세요 질문하기 앞서 좋은 수업 굉장히 잘 듣고 있습니다.
Kafka와 관련된 수업을 들으면서 몇가지 궁금한 사항이 생겨서 여쭤보고 싶습니다. 아직 개발에 미숙하다보니 질문이 이상하다고 생각하실 수 있으시겠지만 답변해주시면 감사하겠습니다 ㅠㅠ...
Spring Boot의 Controller단에서 KafkaTemplate을 이용하여 메시지를 생산하여 Kafka로 보냈습니다. 여기서 몇가지 의문사항이 생기는게 있었습니다.
메시지가 Kafka 서버로 가지 못했을때 상황에 대한 것입니다. 만약 메시지가 가지 못했다면 Catalog 서비스에서 물품 재고 수량에 대한 데이터 불일치가 발생합니다. (개인적으로 Producer가 발행한 메시지가 100% 카프카 서버로 간다고 보장할 수 없을것 같다고 생각합니다. 예를들면 네트워크 상황이 좋지못해서 못보내는 경우)
위의 방안에 대한 해결 방안으로 저는 KafkaProducer가 메시지를 생산하는것을 Transaction 내에 넣으면 되는것이 아닌가? 라는 생각을 하였습니다.
Kafka 서버로 메시지를 보내는것에 실패했을때 주문 자체를 실패시키는것입니다.
하지만 생각했던 위의 방안에 대해서 또한 몇가지 문제가 보입니다.
1. 트랜잭션 내에서 네트워크를 타다보니 성능에 좋지 않은 영향을 미칠 수 있다. ( 트랜잭션 내에서 RestTemplate으로 동기적으로 요청하는것보다는 성능에서 좋을것 같다고 생각합니다.)
2. 메시지가 발행되지 못했다고 해서 트랜잭션을 실패하는게 과연 옳은 일인가?
그래서 위의 2가지 의문으로 Kafka 메시지 생산을 트랜잭션 바깥으로 꺼내는것이 옳은가? 라는 생각이 들었습니다.
제 질문은 어떤 방안이 좀 더 현실적인지에 대한 것입니다. Kafka 메시지 생산을 트랜잭션 내에 넣는것이 옳은 방식일까요?
두번째 질문은
동시적인 상품에 대한 주문 트래픽이 많이 발생하여, Catalog의 재고가 마이너스가 되는 상황입니다. 이런 경우 별개의 로직으로 주문을 취소시키는 로직이 필요할것 같습니다. 여기서 질문은 주문트래픽이 많을때 이러한 상황이 실제로 벌어질 수 있는가에 대한 것입니다.
아직 학생이라 실제 트래픽을 경험해본적이 없어 이러한 상황이 쉽게 발생할 수 있는 상황인지 궁금해서 여쭤보게 되었습니다.
감사합니다
답변 1
2
안녕하세요, 이도원입니다.
말씀하신 것처럼 트랜잭션 처리에 대한 부분이 추가되어야 합니다. 방식은 여러가지가 있겠지만, 작업 요청의 실패 시 다른 서비스간에 업데이트 되었던 모든 데이터의 상태를 이전으로 돌려 놓는 작업은 필요합니다.
이번 강의에서 마이크로서비스 간의 통신을 위한 Kafka를 사용하였습니다. 이는 단순히 서비스간의 통신 방법 중 하나이며, 일반적으로 많이 사용되는 Message Queuing 방식에 대한 예제였습니다. 강의에서 다루는 못한 주제 중, 데이터 동기화에 따른 트랜잭션에 대한 문제가 있는데, 이는 Event Souring 패턴, Saga 패턴등으로 해결해야 합니다. 이번 강의에서 다루기에는 전체 강의가 너무 길어져서 새로 준비하는 강의에서 다룰 주제였습니다. 부록에서도 잠깐 언급했었습니다.
두번째 질문도 유사한 답변이 될것 같습니다. Category 상품에 대한 개수를 업데이터 하기 이전에 수량 확인 후, 커밋과 롤백 등의 처리를 포함 해야 합니다. 취소 시 보상 트랜잭션의 실행으로 이전에 변경된 주문에 대한 데이터를 취소(삭제)해야 하며, 이를 위해, 요청 처리에 대한 모든 명령어 및 이벤트를 기록하는 작업이 필요합니다. Spring framework에서 이벤트소싱에 대한 작업을 위해 Axon framework 등을 사용할 수 있으며, 위에서 말씀드린거와 같이 후속 강의에서 다른 패턴, 마이크로서비스의 구성요소, Spring Cloud이외의 제품으로 구성된 MSA에 대해서 다룰 예정입니다.
감사합니다.