"동기 API만 쓰면 안되나요?"
"실시간도 아니라는데 굳이 비동기 통신을 해야하나요?"
"우리 업무는 실시간으로 처리해야하는데 비동기방식은 안되요"
"실시간이 아니면 현업 설득이 안되요"
"Kafka같은 메세지큐 안해봐서 잘 모르겠어요"
"설계도 개발도 어렵다는데 이벤트 방식이 뭐가 장점인지 잘 모르겠어요"
"그냥 예전처럼 배치로 하면 안되나요?"
"더이타 접합성 맟추기, 동기화하기 어려워요"
"Application Server만 나누고 DB는 통합하면 어때요? 그래도 MSA는 한거잖아요"
"EDA가 뭐에요?"
MSA를 검토하거나, 개발중에 흔히 하는 질문과 생각들이다.
다양한 질문이지만 결론은 다음과 같다.
실시간도 아니라는데, 공수도 더 든다는데, 굳이 왜 서비스를 DB까지 나눠서 비동기 통신까지 해가면서 구현하려는가?
독립적인 개발/테스트/배포 및 확장성, 장애격리 등의 장점을 취할 수 있는 Microservice를 도입한다면 당연히 고려해야하는 방식인데... 하기 싫다는 의미다.
통합DB를 계속 고집한다면 AP만 나누던 기존의 Monolith를 고집하던 잘 할 수 있는 방식, Architecture를 선택 하면 된다.
굳이 MSA를 도입할 이유가 없다고 생각한다.
그런데, 주로 통합 DB, 통합 시스템을 익숙하게 만들고 사용해 왔던 우리나라 상황에서는 이러한 질문과 불만이 있을 수 있다. 하지만 아래와 같은 History나 이유, 장점 등을 직간접적으로 느낀다면 생각이 좀 달라질 수 있다.
도메인에서 발생한 사건을 포착하기 위해 도메인 이벤트를 사용하자. 이벤트는 아주 강력한 모델링 도구다.
일단 도메인 이벤트를 사용하는 법을 알고 나면, 여러분은 이에 중독돼서 어떻게 여지껏 도메인 이벤트 없이 살아왔는지 의아해질 것이다.
- Implementing Domain-Driven Design, 반버논 > 8장 도메인 이벤트 (p377)
1993년도 에릭 에반스가 DDD라는 책을 썼을때만 해도 Domain Event에 대한 특별한 언급이 없었는데 2013년도 반버논의 IDDD책에 포함된 개념이다. 그래서 저렇게 까지 표현했는가 싶다.
도메인 이벤트의 정의 : 도메인 전문가가 관심을 갖고 있는 어떤 사건이 발생했다.
도메인에서 발생한 어떤 일이 도메인 전문가에게 중요한지 어떻게 결정할 수 있을까?
전문가들과 논의를 통해 그들이 알려주는 단서에 귀를 기울여야 한다.
도메인 전문가가 다음과 같은 말을 던질 때 집중하자.
'~할때', '그런 일이 일어나면', '~하면 저에게 알려주세요' 등의 상황
이는 도메인에서 누군가 중요한 일이 발생했기 때문에 알림을 받기를 원하고 있으며, 이는 명시적인 이벤트를 모델링해야 할 여지가 크다는 것을 의미한다.
이벤트를 외부의 서비스로 브로드캐스트해야 할 때 주로 발생하는데,
엔터프라이즈 시스템은 결합에서 분리돼야 하고, 도메인 전반에 걸쳐 일어난 사건은 바운디드 컨텍스트(Microservice 라고 생각해도 됨) 전체로 전달돼야 한다.
이런 이벤트가 발행되면 구독자가 알림을 받게 된다.
구독자가 이런 이벤트를 처리함으로써 로컬과 원격 바운디드 컨텍스트에 광범위한 영향을 미칠 수 있다.
이벤트가 로컬 시스템이든 외부 시스템이든 관심이 있는 대상으로 전달됐을 땐 보통 결과적 일관성(Eventual Consistency)을 위해 사용된다.
이는 분명한 목적을 갖고 설계에 따라 수행된다. (분명한 목적을 갖고 설계해야 한다.)
지연 시간을 감안하면 원격 의존성을 일관성 있는 상태로 유지할 수도 있다.
이런 결합 분리는 높은 확장성과 협업하는 서비스 집합의 최고 성능을 제공하는 데 도움이 된다.
또한 이를 통해 시스템 간의 느슨한 결합을 달성할 수 있다.
- Implementing Domain-Driven Design, 반버논 > 8장 도메인 이벤트 > 언제 그리고 왜 도메인 이벤트를 사용할까 (p378 ~ 379)
해당 도메인(Sub Domain) 에서 중요한 일이 발생했고(과거형) 다른 Sub Domain에서도 알림을 받기를 원하고 있으므로, 이를 잘 파악하기 위해 Event Storming (https://www.eventstorming.com) 이라는 말과 기법을 만들었나보다 생각된다.
도메인 이벤트가 필요한 이유에 대해 하나씩 살펴보면 아래와 같다.
1) Batch 작업 관련
시스템은 사용량이 적은 시간대(아마 밤시간대)에 어떤 종류의 일일 유지 관리를 처리할 텐데,
불필요한 객체를 지우고 새롭게 형성된 비즈니스 상황을 지원하는 데 필요한 것을 생성하고,
일부 객체를 다른 객체와 일치 시키고, 심지어 어떤 사용자에겐 중요한 일이 일어났음을 알려주기까지 한다.
종종 이러한 배치 처리의 수행에선 일부 복잡한 쿼리를 수행해 비즈니스 상황에 주목해야 할지 결정하는 일도 필요하다. 이를 처리하는 계산과 과정에는 큰 비용이 소모되고 모든 변경을 동기화하는 데는 많은 트랜잭션이 필요하다.
만약 이 성가신 배치 처리를 '정리 해고'할 수 있다면 어떨까?
이제 전달 일어난 실제 사건 중에서 나중에 캐치업해야 하는 일이 무엇인지 생각해보자.
만약 이 개별 사건을 각각 하나의 이벤트로 포착해서 시스템의 리스너에게 발행한다면, 일이 간단해지지 않을까?
실제로, 무슨일이 언제 일어났는지 분명히 알 수 있어 그 결과로서 무슨 일이 일어나야 하는지에 관한 컨텍스트를 제공해주기 때문에 복잡한 쿼리를 제거할 수 있다.
여러분은 수신한 각 이벤트의 알림에 맞춰 작업하기만 하면 된다.
현재 I/O와 프로세서 집약적인 배치로 처리되는 사항이 하루 전체로 흩어져 짧게 처리되고, 비즈니스 상황은 훨씬 빠른 시점에 조화를 이뤄서 사용자가 다음 단계를 수행하도록 준비를 마치게 된다.
- Implementing Domain-Driven Design, 반버논 > 8장 도메인 이벤트 > 언제 그리고 왜 도메인 이벤트를 사용할까 (p380)
2) 자치 서비스와 시스템
원격 시스템을 전혀 사용할 수 없는 상황이나 부하가 높은 상황에 놓일 때가 있기 때문에, RPC는 의존성을 갖고 있는 시스템의 성공에 영향을 미친다. 이는 주어진 시스템이 의존하는 RPC API를 가진 시스템의 수가 증가할 때 위험이 배가 된다. 그러므로 서로 묶이는 RPC를 피하는 편이 의존성, 관계된 인스턴스의 완전한 실패, 사용할 수 없거나 너무 낮은 처리량을 가진 원격 시스템으로 인한 허용할 수 없는 수준의 성능 등과 같은 문제를 줄여준다.
다른 시스템을 호출하는 대신에 비동기적 메시징을 사용해 시스템 사이에서 높은 수준의 독립성(자치성 Autonomy)을 달성하자. 엔터프라이즈를 둘러싼 바운디드 컨텍스트로부터 도메인 이벤트드를 전달해주는 메시지를 수신하면, 바운디드 컨텍스트안의 모델에서 해당 이벤트의 의미를 반영하고 있는 행동을 실행하자. 이는 다른 비즈니스 서비스에서 여러분의 비즈니스 서비스로 단순히 데이터를 복제하거나 객체의 정확한 복사본을 만들라는 의미가 아니다. ... 시스템 객체가 주변 객체로 정확하게 복사되는 일은 거의 없다. 이런 모델링 에러가 존재한다면, 바운디드 컨텍스트와 컨텍스트 맵을 참고해서 문제가 된는 이유와 해결 방법을 확인하자.
- Implementing Domain-Driven Design, 반버논 > 8장 도메인 이벤트 > 자치 서비스와 시스템 (p400)
3) 지연시간 허용
메시지를 수신할 때 오래 소요될 수도 있는 지연시간(결과적 일관성까지 수 밀리초 이상의 지연이 나타날 때)이 문제를 유발하지 않을까? 분명히 이는 신중히 고려해야하는 문제이며, 동기화되지 않은 데이터가 잘못된 영향을 미치거나 동작을 망가뜨리기도 한다. 상태의 일관성을 달성하기 위해 얼마나 긴 시간을 허용할지, 감당할 수 없는 한계는 어디인지를 질문해봐야 한다. ... 상태의 일관성을 달성하기까지 초나 분이나 시간 단위를 비롯해서 심지어는 하루가 넘는 기간도 허용 가능할 수 있다는 점은 대부분의 개발에게 놀라움으로 다가온다.
때론 다음과 같은 질문이 의미 있는 답으로 이어질 수 있다.
컴퓨터를 다루이게 앞서 비즈니스 관계자는 어떻게 일하는가? (Event Storming 등을 통해 파악 가능)
컴퓨터 없이 작업하진 않는가? ...
자동화된 컴퓨터 시스템도 허용 범위가 있어야 하고, 결과적 일관성의 방식이 심지어 광범위하게 사용되고 있다는 사실도 이해할 수 있다. ...
몇 초 가량의 전형적인 지연은 허용할 수 있을 뿐만 아니라 문제가 되지 않는다.
사실 실제 지연이 발생하더라도 인식하지 못할 수도 있다. ...
최대 허용 지연 시간을 잘 이해해야하며, 시스템 허용치를 만족시키면서도 더 잘 수행되도록 아키텍처 품질을 높여야 한다. 자치 서비스와 서비스에서 지원하는 메시지 인프라는 반드시 고가용성과 확장성을 갖도록 설계해야하고, 이를 통해 엔터프라이즈의 엄격한 비기능적 요구사항을 충실히 만족시켜야 한다.
- Implementing Domain-Driven Design, 반버논 > 8장 도메인 이벤트 > 지연시간 허용 (p401)
4) 분산 시스템은 근본적으로 다르다
문제는 분산 시스템에 익숙하지 않은 개발자가 내재하는 복잡성을 얼버무리고 넘어갈 때 발생한다. 이는 특히 RPC를 사용할 때 그런데, 분산 경험이 미숙한 사람들은 보통 모든 원격 호출이 인프로세스 호출처럼 쉽다고 생각하기 때문이다. 이런 가정은 단 하나의 시스템이나 컴포넌트가 단지 일시적으로라도 사용이 불가능해질 때 많은 수의 시스템에 걸쳐서 연쇄적인 실패를 야기할 수 있다. 그러므로 분산 시스템 내에서 작업하는 모든 개발자는 다음과 같은 분산 컴퓨팅의 원칙을 따르는지에 따라 성공 여부가 결정된다.
. 네트워크는 신뢰할 수 없다.
. 언제나 지연이 있을 수 있고, 많을 수도 있다.
. 대역폭은 무한하지 않다.
. 네트워크가 안전하다고 가정하지 말라.
. 네트워크의 위상(Topology)은 변화한다.
. 정보와 정책은 다수의 관리자에 걸쳐 퍼져 있다.
. 네트워크 전송은 비용이 든다.
. 네트워크는 다양성을 갖고 있다.
이를 원칙이라고 부른 이유는 반드시 해결해야 하는 문제점이고 계획해야 하는 복잡성이지, 초보가 일반적으로 저지르는 실수는 아님을 강조하기 위해서다.
- Implementing Domain-Driven Design, 반버논 > 8장 도메인 이벤트 > 분산 시스템은 근본적으로 다르다 (p573 ~ p574)
5) 통합의 기본
(1) API : 프로시저 호출 스타일을 지원하기 때문에 프로시저나 메소드를 호출하는데 익숙한 프로그래머들이 이해하기 쉽다.
(2) 메시징 매커니즘 : 상호작용해야하는 각 시스템은 메시지 큐나 발행-구독 메커니즘을 사용한다.
(3) DB통합 : DB통합을 사용할 수도 있지만, 이런 방법은 여러분을 너무 빨리 늙어버리게 만든다.
- Implementing Domain-Driven Design, 반버논 > 8장 도메인 이벤트 > 통합의 기본 (p572 ~ p573)
'MSA해설 > EDA' 카테고리의 다른 글
EDA로 가라 (0) | 2022.12.06 |
---|---|
Event Driven Architecture 정의 (0) | 2022.12.02 |
Batch? Event? (0) | 2022.11.10 |
분산 시스템은 근본적으로 다르다? (0) | 2022.09.01 |
Domain Event, CQRS 적용 예 (배민) (0) | 2022.04.02 |