들어가며..
마이크로 서비스 아키텍처(MSA) 프로젝트를 개발 및 운영을 하다 보면 도메인 모델은 복잡해지고 점점 설계 시점의 의도와는 다른 방향으로 변질되는 일이 빈번히 발생한다. 특히 요즘처럼 고차원적인 UX, 급변하는 IT 시장의 흐름으로 인해 시도 때도 없이 달라지는 기획팀/사업부의 요구사항을 충족하는 모델을 만드는 건 더욱 어려운 일이 되었다. 게다가 이렇게 복잡한 내용을 하나의 화면에서 다 보여달라고 하니.. 아무리 인덱스를 추가하고 쿼리를 튜닝하더라도 조회 속도가 나지 않고, n번의 api를 결과를 합치면서 생기는 실수, 더러운 소스코드 등은 결국 서비스의 질을 낮추기에 충분해진다.
이게 왜 어려워졌을까? 데이터의 변경과 조회 시 필요한 데이터가 관점에 따라 명백히 다른데, 이걸 하나의 모델/애플리케이션/디비에서 해결하려다 보니 (각 영역에서 필요하지 않은 속성들로 인해) 복잡도가 증가하고 변질되는 것은 아닐까?
그럼 어떻게 이 문제를 해결 할 수 있을까? 데이터의 변경과 조회를 나누면 되지 않을까? 해서 나온 게 CQRS이다.
CQRS란?
마이크로 서비스의 패턴이 무려 44가지나 있다고 하는데, 간단하게 관련 용어 몇 가지만 살펴본다.
- DDD - Domain Driven Design 도메인 주도 개발(방법론)
- 비즈니스를 도메인 별로 나누어 설계하는 방식/접근법
- EDA - Event Driven Architecture
- 분산된 시스템 간에 이벤트를 생성, 발행(publishing)하고 발행된 이벤트를 필요로 하는 수신자(subscriber)에게 전송되는 흐름으로 구성된 아키텍처로 이벤트를 수신한 수신자가 이벤트를 처리하는 형태임
- Architectural Patterns
- CQRS - Command Query Responsibility Segregation 패턴
- "CQRS는 DDD 기반의 Object Model 방법론 적용 시 나타났던 문제점들을 해결하기 위해 등장했다"
- Architectural Patterns
- 작성 글: 2022.01.11 - [architecture/micro service] - [arch] cqrs란 - 조회와 비조회의 엄연한 분리
- Aggregate Pattern
- DDD에서 소개된 설계 패턴
- Aggregate는 서로 관련이 있는 도메인 모델들의 집합; 데이터 변경의 단위
- 작성 글: 2022.01.13 - [architecture/micro service] - [arch] DDD pattern 와 aggregate란
- Saga Pattern
- MSA 기반의 분산 시스템에서 분산된 DB의 정합성을 보장하는 방법, 트랜젝션 관리주체는 애플리케이션(not DB)
- sequence diagram을 따라가다(transaction flow 속에서) rollback이 필요할 때 처리하는 방법
- Choreography-Based Saga(각자 알아서 처리)
- Orchestration-Based Saga(중앙 컨트롤 타워가 정리)
DDD is well suited with some architectural patterns like CQRS, Event Driven Architecture, Event sourcing, etc but they are not required to use DDD.
CQRS를 구현할 수 있게 하는 axon framework
- axon framework는 DDD 패러다임 하에서 event sourcing과 CQRS 패턴을 이용해 애플리케이션을 작성할 수 있도록 도와주는 framework
- 작성 글: [cqrs] axon framework란
실습
환경: springboot2.6.2 / axon framework 4.2.1 + axon server / postgresql14
1. axon server를 설치하고
2022.01.12 - [서버 세팅 & tool/vm on mac] - [vm] axon server 설치
2. springboot project에 axon dependencies 올려서 개발
axonVersion = "4.2.1"
implementation group: 'org.axonframework', name: 'axon-spring-boot-starter', version: "$axonVersion"
implementation group: 'org.axonframework', name: 'axon-configuration', version: "$axonVersion"
3. 블로그 흐름 따라가며 개발하였고
https://cla9.tistory.com/2?category=814447
4. 개발하면서 막히는 부분/ 깨달은 부분은 따로 정리
2022.01.12 - [개발/axon framework] - [axon] command/query project 생성 - clone coding
5. 깃에 등록
https://github.com/haileyjhbang/cqrs-clone.git
axon framework 구조
Command Applcation
- Event-Sourced Aggregate: EventStore로부터 Event를 재생하면서 모델을 최신 상태로
- State-Stored Aggregate: EventStore에 Event를 적재와 별개로 모델 자체에 최신 상태를 DB에 저장
Query Application
- Point to Point Query: 하나의 QueryHandler를 찾아 진행
- Scatter-Gather Query: 동일한 Query를 처리하는 Handler가 여러 App에 등록되어있을 때, 이를 처리하는 방법
- Subscription Query: Point to Point Query를 요청하였을 때, 만약 Query를 수행하는 Read Model이 바뀌었다면, 화면에 출력되는 결과와 Read Model 사이 데이터 정합성 불일치 문제가 발생한다. 따라서 이를 해결하기 위해 주기적으로 Query를 재요청하는 방식
추가) Saga pattern in axon
axon framework에서도 분산 트랜젝션을 위해 saga 패턴을 지원한다(saga event 정보를 db에 저장).
//어노테이션
@StartSaga
@SagaEventHandler(associationProperty = "transferID")
@EndSaga
//함수 호출방식
SagaLifecycle.associateWith("accountID", event.getDstAccountID());
SagaLifecycle.end();
활용방안?
초기 그림의 MSA 구조의 시스템 & 대용량 처리가 필요한 시스템에 적용하면 효과적인 대안이 될 수 있을 것이란 생각이 들었다. ES 전파만 확실하면 쿼리 성능도 좋아질 것이고 두 애플리케이션의 결합도도 낮아 독립적인 스캐일 업 또한 가능할 것이다.
하지만 러닝 커브의 압박, 분산된 구조로 인한 트러블 포인트의 증가, 서비스 복잡도 증가 그리고 DB를 많이 쓰기 때문에 유능한 DBA나 넉넉한 DB공간 확보 필요 등의 비용이 많이 들 수 있어 비즈니스 로직이 간단한 서비스면 굳이 도입할 필요는 없을 것 같다.
참고
https://docs.axoniq.io/reference-guide/
책: 마이크로 서비스 패턴(Chris Richardson 저)
http://www.yes24.com/Product/Goods/86542732
요약본: https://microservices.io/patterns/index.html
'개발 > axon framework' 카테고리의 다른 글
[axon] saga (2) - clone coding (0) | 2022.02.18 |
---|---|
[axon] saga (1) - clone coding (0) | 2022.02.18 |
[axon] query handler(2) - clone coding (0) | 2022.02.14 |
[axon] query handler(1) - clone coding (0) | 2022.02.11 |
[axon] event upcasting - clone coding (0) | 2022.02.04 |