MSA(MicroService Architecture)는 소프트웨어 개발 기법의 하나입니다. MSA는 단일 애플리케이션을 작은 서비스 모음으로 개발하는 접근 방식입니다. 각각은 자체 프로세스에서 실행이 되고 느슨한 연결(Loosely-coupled) 구조로 만들어 HTTP 리소스인 REST와 같은 경량 메커니즘과 통신을 합니다. 한마디로 "하나의 큰 애플리케이션을 여러 개의 작은 애플리케이션으로 쪼개어 변경과 조합이 가능하도록 만든 아키텍처"입니다.
MSA 방식은 넷플릭스의 마이크로서비스 전환 성공 사례와 넷플릭스 OSS(Open Source Software)라고 불리는 오픈소스 기반의 프레임웍이 좋은 레퍼런스가 되면서 많은 기업이 모놀로식(Monolithic) 아키텍처에서 MSA로 전환을 시도하고 있습니다.
5~6년 전부터 MSA에 대해서 많은 논의가 있어왔습니다. MSA와 같은 모듈형 아키텍처 스타일은 클라우드 기반 환경에 적합해 높은 인기를 구가하고 있습니다. 특히 도커(Docker), 쿠버네티스(Kubernetes) 등과 같은 컨테이너 기반의 플랫폼과 조합이 잘 어우러지면서 클라우드 플랫폼과 MSA는 서로 끌어주고 밀어주면서 발전하고 있습니다. MSA는 아마존, 넷플릭스, 이베이와 같은 글로벌 서비스 기업들이 사용할 만큼 강력한 아키텍처입니다. 하지만 막상 MSA를 적용하려고 하면 다음과 같은 난관에 부딪히게 됩니다.
분산 시스템 개발은 일반 개발보다 복잡합니다. 독립적인 서비스이기 때문에 각 모듈의 인터페이스를 신중하게 처리해야 합니다. 요청에 응답하지 않게 될 경우에 대한 방어 코드도 작성해야 하며 호출 대기 시간이 일정 수준을 넘기면 복잡한 상황이 발생할 수 있습니다. 또한 동기적인 처리방식인 REST 통신으로 인한 제약이 발생할 수 있습니다.
MSA는 Database Per Service라는 새로운 요구사항으로 분산된 서비스마다 분리된 DB들 간의 트랜잭션 관리가 어려울 수 있습니다. 또한 반정규화 된 데이터의 동기 처리도 신경을 써야 합니다.
MSA 기반의 애플리케이션을 테스트하는 것은 번거로울 수 있습니다. 테스트를 시작하기 전에 의존성이 있는 서비스를 미리 확인해야 합니다.
MSA의 배포는 복잡 할 수 있습니다. 각 서비스 간의 조정이 필요 할 수 있습니다.
MSA를 도입하다보면 기존에 없던 새로운 문제점들이 발생합니다. 이런 부분들은 자동화 도구를 사용하거나 비즈니스 상황에 맞게 수정된 아키텍처를 적용하여 해결할 수 있습니다. 본 아티클에서는 MSA가 적용된 시스템을 보완하는 Event Driven MircoService(EDM)를 소개하려고 합니다.
Event Driven은 IT 영역에서 아주 오래된 키워드입니다. 최근에 다시 주목을 받으며 2018년 가트너에서 선정한 유망한 기술 트렌드 중 하나로 뽑히기도 했습니다.
Event Driven 아키텍처는 특정 서비스에서 다른 서비스가 관심을 가질 수 있는 일부 작업을 수행할 때 해당 서비스는 이벤트(작업의 기록)를 생성합니다. 다른 서비스는 이벤트들을 전달받고 필요시 자체 작업을 수행할 수 있습니다. REST와는 달리 이벤트를 통해 느슨한 구조로 요청을 생성하는 서비스는 요청을 소비하는 서비스의 세부 정보를 알 필요가 없습니다.
이벤트는 다양한 방법으로 게시할 수 있습니다. 예를 들어 이벤트를 적절한 소비자에게 전달하도록 보장하는 대기열(Queue)에 게시하거나 이벤트를 게시하고 모든 이해 당사자에게 액세스를 허용하는 "발행-구독"(Pub-Sub) 메시지 모델에 게시할 수 있습니다. 두 경우 모두 생산자는 이벤트를 발행하고 소비자는 해당 이벤트를 수신하여 그에 따라 반응합니다. 이 두 행위자를 발행자(생산자)와 구독자(소비자)라고 불립니다.
Queue처리 방식으로는 대표적으로 ActiveMQ, RabbitMQ가 있으며 메시지 모델로는 대표적으로 Apache Kafka를 많이 활용합니다.
Apache Kafka는 Event Driven 아키텍처에 사용되어 라우팅을 통한 "발행-구독"(Pub-Sub) 메시지 스트리밍에서 데이터를 메시지 저장소에 넣습니다. 이벤트 데이터는 추가 처리 및 분석을 위해 분석 플랫폼인 Storm/Spark을 통해 SQL·NoSQL 데이터베이스에 저장할 수 있습니다. MSA 내의 서비스들이 복잡해지면 지점 간 데이터 파이프라인의 복잡성으로 인해 중앙 저장소가 필요합니다.
MSA에서 내부 통신은 크게 2가지 방식이 사용됩니다. 이들 모두 장점과 단점이 있으니 상황에 따라 적합한 방식을 선택하면 됩니다.
요청·응답 모델은 동기 통신에 단일 통신 방법입니다. 즉 요청자는 응답자의 주소를 알고 있어야 통신이 가능합니다. 이런 방식을 Point to Point 방식이라고 합니다. 이 방식은 서비스가 증가할수록 기억해야 할 주소가 늘어납니다. 서비스가 복잡하게 연결되어 있어 스파게티 네트워크(Spaghetti network)라고도 불립니다. 동기 통신이기 때문에 응답 서비스가 항상 떠 있어야 하고 응답 서비스에서 오랜 시간을 소비하면 그만큼 응답이 늦어지기에 Blocking 모델입니다. 또한 요청 체인이 길어지면 장애 전파(Fault Spread)의 위험성이 있습니다.
이에 반하여 발행-구독 모델은 비동기 통신에 Broadcasting이 가능합니다. 이벤트 게시자는 구독자의 주소를 몰라도 되고 이벤트를 수신했는지 여부를 파악하지 않아도 되는 Non-Blocking 모델입니다. 수신자의 서비스가 항상 떠 있지 않아도 게시자는 메시지를 발송할 수 있습니다. 이로 인하여 장애가 격리(Fault Isolation) 됩니다. Even Driven 애플리케이션에서는 발행-구독 모델을 선택합니다.
EDM은 MSA가 적용된 시스템에서 이벤트 발생 시 해당 이벤트 로그를 보관하고 이를 기반으로 동작하며 비동기 통신을 통해 시스템 내 통합을 수행하는 아키텍처입니다.
Database Per Service는 MSA의 느슨한 결합, 관심사의 집중, 폴리글랏 프로그래밍, 독립적인 배포 주기 등을 달성하기 위한 핵심 키워드입니다. 하지만 MSA를 적용할 때 Database Per Service는 가장 어려운 부분 중 하나입니다.
기존의 Shared Database 구성, 그 중 관계형 DB를 사용하는 경우 ACID 원칙에 따른 트랜잭션 처리, 데이터 무결성, 모든 테이블에 접근해 Join을 통한 통합 뷰 제공, 관계를 활용한 효율적인 데이터 저장·조회 등 DBMS 레벨에서 여러 유용한 기능을 제공했습니다. MSA에서 Database Per Service를 적용하면 Shared Database 구성의 DBMS 레벨에서 제공하던 기능을 애플리케이션 레벨에서 해결해야 합니다. EDM은 DBMS 레벨이 아닌 애플리케이션 레벨에서 최종 일관성을 지원해 트랜잭션 처리를 수행하는 것에 적합하며 서비스의 목적에 최적화된 DB를 선택하는 것에 도움을 줍니다.
비즈니스 흐름에 따라 기능을 수행하다가 중간에 문제가 발생할 수 있습니다. 문제가 발생한 시점에 롤백(Rollback) 또는 재시도(Retry)를 수행합니다.
기존 레거시 시스템에서 문제 발생 시 일관된 commit 또는 롤백 처리나 이전에 발생한 상태 변경에 직접 접근해서 데이터 수정이 가능합니다. 하지만 MSA가 적용된 시스템에서 서로 다른 서비스에 걸쳐진 기능을 수행하는 도중 일관된 commit 또는 롤백을 수행할 수 없습니다. 이때 EDM을 적용해 롤백 또는 재시도하여 처리할 수 있습니다. 롤백이 필요한 경우 Failed 이벤트를 발생시키고 이를 이전 스텝을 수행한 서비스에서 구독하여 보관되어 있던 이벤트 로그 기반으로 롤백을 수행합니다. 재시도가 필요한 경우 메시지 큐의 Requeue 또는 Dead-Letter Queue 기능을 사용해 재시도 처리를 수행할 수 있습니다.
MSA가 적용된 시스템에서는 비즈니스 로직과 이를 수행하는데 필요한 데이터가 서로 다른 서비스에 나누어져 있을 수 있습니다. 처음에는 여러 서비스 간 REST 통신을 통해 데이터 참조를 수행할 수 있으나 서비스가 커지면서 복잡성·성능 등의 이슈로 서비스 간 데이터 반정규화가 발생할 수 있습니다. 이때 EDM을 적용해 서비스 간 데이터 동기 처리를 수행할 수 있습니다.
기존의 DBMS를 활용한 ACID 트랜잭션에 따른 데이터 무결성 보장은 MSA에서 서비스, DB가 나누어 가짐으로써 더는 달성할 수 없습니다. 대신 EDM을 사용해 데이터의 최종적인 일관성 유지로 변경됩니다.
( all commit or rollback → eventually consistency )
Event Driven Microservice의 요구사항 및 달성 효과는 전혀 새로운 것이 아닙니다. DBMS 내 트랜잭션 로그를 활용한 redo·undo 로직, 이기종 DB 간 분산 트랜잭션 처리, 외부 시스템과 I/F를 통해 업무를 처리할 때 상이한 시스템 간 정합성 처리 등 기존에 다루던 문제들과 요구사항 및 구현 방식이 비슷합니다.
EDM은 MSA 도입 시 발생하는 새로운 요구 사항을 달성하는 개념입니다. 서비스, DB의 분리, 폴리글랏 등에 대응해 효과적으로 동작합니다. EDM은 실패를 허용하는 분산 구조, 이벤트 브로커 등을 통해 문제를 해결하고 MSA 도입의 난관을 해결할 수 있도록 도와줍니다.
기존의 모놀로틱 아키텍처의 단점 및 한계를 해결하고자 하거나 클라우드 환경에서 시스템을 구축할 때 얻을 수 있는 장점 때문에 MSA 도입을 결정했다면 그 다음 닥칠 문제에 대비해 EDM을 고려해볼 필요가 있습니다.
References
- https://martinfowler.com/articles/microservices.htm
- http://www.msaschool.io/operation/integration/integration-three
- https://medium.com/dtevangelist/event-driven-microservice-%EB%9E%80-54b4eaf7cc4a
- https://hackernoon.com/best-practices-for-event-driven-microservice-architecture-e034p21lk
- https://www.tmaworld.com/2017/11/14/top-10-strategic-technology-trends-2018/
- https://www.confluent.io/blog/using-apache-kafka-drive-cutting-edge-machine-learning/
- https://softobiz.com/understanding-the-event-driven-architecture/
▶ 해당 콘텐츠는 저작권법에 의하여 보호받는 저작물로 기고자에게 저작권이 있습니다.
▶ 해당 콘텐츠는 사전 동의 없이 2차 가공 및 영리적인 이용을 금하고 있습니다.
에스코어㈜ 소프트웨어사업부 오픈소스SW그룹
빅데이터 및 오픈소스SW 관련 연구 개발 프로젝트를 수행하였으며 현재 OSS 기술서비스와 아키텍처를 담당하고 있습니다.