인프런 커뮤니티 질문&답변

ello님의 프로필 이미지
ello

작성한 질문수

Spring Cloud로 개발하는 마이크로서비스 애플리케이션(MSA)

Event Sourcing + CQRS + Saga Pattern

MSA와 사가 패턴을 찾아보면서 궁금했던 부분이 있어서 질문 남겨봅니다.

작성

·

1.1K

0

모든 자료가 그런 것은 아니지만 많은 MSA 관련 자료가 EDA (Event-Driven Architecture)를 이야기하고 있고, 카프카를 도입하면서 느슨하게 연결되어있고 원하는 메시지만 수신할 수 있도록 하는 구조로 설명을 하는 것 같습니다. (메시지 큐를 도입했을 때의 문제점에 대한 이야기는 별로 없고, 그 이상의 무언가를 찾거나 노하우를 구하기 쉽지 않은 듯 하네요.)

디커플링 자체는 상당히 좋은 장점 중 하나이지만, 개별 시스템으로 분리되면서 트랜잭션 관련해서도 고민이 많이 필요하고 연결하는 고리가 많아지는 만큼 신경써야 할 부분도 많을 것으로 보입니다.

그래서 들었던 질문이 몇 가지 있는데 마땅히 답을 구할만한 곳이 없었는데 이 쪽에서 관련된 질문에 답을 해주실 것 같아 달아봅니다.

1. 이벤트 소싱에 대해 맞게 이해한 것인지 ?

우선 이벤트 소싱이 CQRS, 비동기 처리와 많이 엮여서 나오는 주제이긴 하지만 이벤트 소싱 자체만을 두고 봤을 때에는

1) 이벤트의 모든 이력을 남기고
2) 핸들러가 이를 처리하는 것이 전부

라고 이해해도 될까요 ?

CQRS는 표면적으로는 변경과 질의를 분리하는 개념이지만, 이벤트 기록을 모두 재생해서 조회하는 것이 어려워서 질의와 변경을 분리하는 아이디어 때문에 이벤트 소싱에서 함께 언급되는 패턴으로 이해했고, 비동기 처리는 이벤트 소싱이 비동기 처리를 편하게 할 수 있는 환경 정도로만 이해했습니다.

제가 이해한게 맞는지 모르겠어서 잘 이해했는지 질문을 드리고 싶구요 ㅎㅎ

2. 짧은 시간 안에 처리되어야 하는 API도 MSA에 적합한가 ?

위에 제가 이해한 것이 맞다는 가정하에 말씀드리는 거긴 한데요. 예를 들면 만약에 OTT에서의 유료 영상 결제, 문서 파일 결제, 웹툰 등에서 결제하자마자 결과를 검증하고 사용해야 하는 과업이 있고, 이 과업을 단일 API로 처리하던 것을 MSA로 전환할 경우에

1) API, gRPC 등 네트워크 통신을 사용하는 MSA의 경우 : 코드나 개념적인 분리를 통해 서비스를 작게 쪼갤 수 있는 장점은 있지만 네트워크 이슈, 롤백 등 신경써야 할 문제가 많아진다

2) 카프카 등의 메시지 큐를 통한 MSA일 경우 : 카프카 자체의 문제 혹은 처리하는 개별 마이크로 서비스에 병목이 생기면 처리가 지연되며, 단일 API로 주고받던 경우에는 앱 수정이 불가피하다 (카프카를 사용하면 더더욱 이벤트 소싱을 고려할 수밖에 없고 PENDING 상태가 기존 앱에서 정의되지 않았기 때문에) 는 문제가 있을 것 같습니다.

아무래도 제가 카프카를 넣는 것이 우려가 되는 이유는

1) 각 서비스에서 발행한 카프카 메시지를 어떻게 추적하는지 쉽지 않다고 생각했고,
2) 장애 포인트가 쪼개지는 서비스와 개념적으로 발생하는 연결의 갯수에 비례해서 많아지기 때문이라 생각했고,
3) 또한 카프카를 통해서 처리하는 속도가 API로 처리하는 지금 속도 대비 느리게 세팅된 상태라 과하게 생각하는건가 싶기도 하고,
4) 앱에서 '서버의 아키텍쳐 변경을 위해 생긴 PENDING 상태에 대해 알고 있어야 하는가'에 대해서 고민이 많아서

그런 것 같습니다. 제가 MSA 관련해서는 경험이 없다보니 의견을 좀 들어보고 싶습니다.

3. 보상 트랜잭션과 관련하여

각자의 로컬 트랜잭션만 보장하고 문제가 생기면 그게 반하는 트랜잭션을 새로 발행해서 상태를 상쇄시키는 형식인 것 같습니다.

상태 머신이 명확하게 구분된다면 보상 트랜잭션 구현이 용이하겠지만, 그렇지 않을 경우나 모호한 경우가 있을 것이라 생각됩니다.

또한 보상 트랜잭션이 실패하는 경우 더더욱 현상 파악이 쉽지 않을 것 같기도 하고, 구현하는 서비스마다 제각각이라 노하우를 구하기 쉽지 않을 것으로 보여서 구현 난이도가 꽤 올라갈 것으로 보이는데, 이런 부분을 보완할 수 있는 방법이 있을지 궁금합니다.

답변 1

8

Dowon Lee님의 프로필 이미지
Dowon Lee
지식공유자

안녕하세요, 이도원입니다. 

문의하신 질문에 대한 제 의견을 간략하게 나마 달아드립니다. 

1. 이벤트소싱의 핵심은 트랜잭션에서 발생된 정보를 순서대로 기록하고, 변경 내역의 재성을 통해 데이터의 상태를 확인할 수 있다는 점입니다. MSA에서는 각 서비스마다 데이터를 저장할 수도 있는 구조이기 때문에, 데이터의 정합성을 보장하기 위해 사용할 수 있으며, 저장된 데이터의 읽기 성능을 높이기 위해 CQRS과 같이 사용하는 경우가 많습니다. 

2. MSA를 설계할 때의 핵심은 데이터 구조를 어떻게 설계하고, 동기화는 어떻게 처리할 지에 대한 부분이라고 생각합니다. MSA에서 데이터 스토리지의 분리가 필수는 아니라고 생각하며, 필요에 따라 단일 DB, 공유 DB를 사용할 수 있습니다. MSA 구조로 아키텍처를 설계했다면 거기에 맞는 서비스 분리 기준을 정해야 합니다. MSA 단점 중에 하나는 네트워크 트래픽이 발생 할 수 있다는 점입니다. 속도가 중시 될 경우에는 gRPC를 사용할 수 있으며, 데이터 동기화와 롤백 처리를 위해 이벤트 소싱이나 CQRS, SAGA와 같은 구현 모델이 사용되고 있습니다. 말씀하신 내용처럼 서비스가 많아지는 만큼 장애 포인트가 많아 질수도 있겠지만, 이것은 SPOF를 생성하지 않고 확장할 수 있다는 장점을 가져올 수 있습니다. 이러한 단점과 대체 기술들의 사용성 등을 고려하여 MSA로 분리할 지를 결정해야 한다고 생각됩니다. 카프카는 서비스 간의 데이터 전송 부분에 있어 사용할 수도 있으며, API를 처리하기 위한 용도로 사용할 수도 있습니다. 카프카 클러스터를 어떻게 구성하느냐에 따라 다르겠지만, 안정적인 데이터 전송을 보장할 수 있으며, MSA에서는 비지니스 로직에 충실할 수 있을거라 생각됩니다. 서비스의 빠른 응답속도 및 피드백이 요구되는 부분에서는 MSA의 서비스 구분 단위를 다시 정의해서 설계하는 것이 필요할 것 같습니다.

3. 이 부분은 데이터 동기화에 관련된 정책이 같이 고려되어야 할 것 같습니다. 보상 트랜잭션을 구성하기 위해 서비스 단위로 트랜잭션을 관리할 지, 트랜잭션을 위한 별도의 인스턴스를 구성하여 관리할 지 선택할 수 있습니다. 말씀하신 내용처럼 보상 트랜잭션이 실패하는 경우의 가정은, MSA에서만 존재하는 것이 아니라, 일반적인 DB 애플리케이션에서 트랜잭션을 잘못 처리할 때도 충분히 발생할 수 있는 오류랴고 생각됩니다. SAGA를 통한 보장트랜잭션 관리를 위한 프래임워크를 도입하여 위험을 최소화 할수는 있다고 생각됩니다. 

추가 질문사항 있으시면 다시 글 남겨 주세요.

감사합니다. 

ello님의 프로필 이미지
ello

작성한 질문수

질문하기