Monolithic Architecture와 MicroService Architecture
MSA는 MicroService Architecture의 줄임말로, 애플리케이션을 느슨하게 결합한 서비스의 모임으로 구조화하는 서비스 지향 아키텍처(SOA) 스타일의 일종인 소프트웨어 개발 기법이다.
서비스 지향 아키텍처(SOA, Service Oriented Architetcutre)
애플리케이션 구성요소끼리 통신 프로토콜을 통해 다른 구성요소에 서비스를 제공하는 아키텍처 접근 방식이다. 대규모 컴퓨터 시스템을 구축할 때, 소프트웨어의 독립적 기능을 서비스로 판단하여 여러 서비스들을 네트워크로 연동하여 시스템 전체를 구축하는 방법을 말한다.
소프트웨어 모든 구성요소를 한 프로젝트에 통합되어있는 Monolithic Architecture는 형태가 간단하며 유지보수가 용이하다. 하지만 애플리케이션의 규모가 일정 수준을 넘어가면 Monolithic 구조는 여러 한계점들이 잇다.
•
부분 장애가 전체 서비스의 장애로 확대될 수 있다.
•
서비스 변경이 어렵고, 변경사항 발생 시 사이드 이펙트의 파악이 힘들다.
•
빌드 시간 및 테스트 시간, 배포 시간이 오래 걸린다.
•
서비스의 특정 부분만 스케일 아웃(scale-out) 하기 어렵다.
이런 한계점을 해결하기 위해 MSA가 도입되었다.
MSA의 마이크로 서비스는 해당 서비스의 end-point(접근점)을 API 형태로 노출하고, API를 통해서만 상호작용한다. 그 외의 각 서비스의 내부 구현 로직이나 아키텍처, 프로그래밍 언어, 데이터베이스 등 실질적인 세부 사항은 모두 추상화하여 서비스 API에 의해 철저하게 가려진 채로 사용한다.
제대로 설게된 마이크로 서비스는 하나의 비즈니스 범위에 맞춰 만들어지므로 단 하나의 기능만 수행해야 한다. 다시 말해, 각자의 마이크로 서비스는 자기가 개발하는 서비스만을 책임진다. 또한 여러 애플리케이션에서 재사용할 수 있을만큼 추상화 되어있어야 한다.
애플리케이션은 항상 기술 중립적 프로토콜(특정 기술에만 적용할 수 있지 않은 범용적인 프로토콜)을 사용하여 통신하므로 서비스 구현 기술과는 무관하며, 때문에 각 마이크로 서비스는 다양한 언어와 기술로 구축될 수 있다.
MSA는 SOA에서 사용되는 집중화된 관리 체계를 사용하지 않고, ESB(Enterprise Service Bus)와 같은 무거운 제품에 의존하지 않는다. REST 통신과 같이 가벼운 통신 아키텍쳐를 사용하고, Kafka 등 mssage stream을 주로 사용한다.
MSA의 장단점
MSA의 장점은 다음과 같다.
•
특정 서비스만 별도로 배포하거나 각 서비스별로 배포하는 것이 가능하고, 때문에 배포 시에 전체 서비스의 중단이 없다.
•
여러 서비스에 대한 scale-out 확장에 용이하고, 때문에 클라우드 기반의 서비스에 적합하다.
•
부분 장애가 마이크로 서비스로의 장애에서 그치고, 전체 시스템의 장애로 이어지지 않을 가능성이 높다.
•
각 마이크로 서비스마다 다양한 언어와 기술을 사용할 수 있기 때문에, 새로운 기술을 유연하게 도입할 수 있다.
반면 MSA를 사용하는 것에 대한 단점은 다음과 같다.
•
MSA는 모놀리식에 비해 상대적으로 구조가 복잡하고, 개발자가 내부 시스템의 구조와 통신을 어떻게 가져가야 할 지 결정해야한다.
•
서비스 간 호출 시 API를 사용하기 때문에 통신 비용이나 Latency에 대한 이슈가 발생할 수 있다.
•
기본적으로 API로 통신하기 때문에 트랜잭션을 어떻게 유지할지 미리 결정해두어야하고, 통신 장애나 서버의 부하와 같은 상황에서 트랜잭션을 어떻게 해결할지 구현해두어야 한다.
•
여러 서비스로 기능이 분리되어 있기 때문에 통합 테스트가 어렵고, 개발 환경과 실제 운영 환경을 동일하게 가져가는 것이 쉽지 않다.
•
데이터가 여러 서비스에 분산되어 있기 때문에, 모놀리식 구조보다 데이터를 조회하거나 관리하는데 많은 신경을 써야한다.
•
각 서비스를 배포할 때마다 다른 서비스들과의 연계가 정상적으로 이루어지는지도 확인해야 한다.
MSA는 빌드, 테스트, 배포 속도와 유연성, 유지관리 용이성으로 인해 비즈니스 민첩성(Business agillity)과 관련이 크고, 이런 장점으로 인해 서비스나 프로젝트가 크고 복잡하고 장기적으로 운영될수록 MSA를 채택하는 것이 더 많은 이점을 가지고 있다.
MSA 설계와 전환
기존의 모놀리식 애플리케이션을 MSA로 전환하는 방법은 단번에 전체 구조를 전환하는 빅뱅(Big Bang) 방식과 조금씩 떼어내서 점진적으로 MSA로 전환하는 스트랭글러(Strangler) 방식이 있다.
빅뱅 방식은 전체 업무 영역을 단번에 MSA로 구축하기 때문에 IT 인프라 전체를 개선할 수 있지만, MSA로 전환하는 동안 다른 작업을 못하는만큼 빠르게 진행되어야만 한다.
스트랭글러 방식은 우선순위를 적용하여 시급한 서비스를 MSA로 전환할 수 있어 효율적이지만, 전체 시스템의 MSA 전환까지 굉장히 오랜 시간이 걸릴 수 있다.
MSA를 설계하는데 있어서 핵심은 전체 시스템에서 각 마이크로 서비스로 쪼개는 것이다. 서비스를 쪼개는 과정은 목표 설정 → 서비스 분리 → 평가 검증 → 서비스 설계의 4단계로 구성된다.
MSA 도입의 목적이 비즈니스의 빠른 변화에 대응하기 위함인지, 서비스의 독립성을 확보하기 위함인지를 분명히 해야한다. 이를 통해 어떤 기준과 어떤 수준으로 쪼갤지 결정하고 이벤트 스토밍, 후보 서비스 식별, 서비스 관계 정의 등의 작업을 수행한다.
이후 후보 서비스들 중에 신규 추가나 변경이 잦은 업무를 별도로 분리하고, 부하나 장애 등의 이유로 독립성을 확보해야하는 서비스를 식별한다.
서비스를 분리하고 나면, 각 서비스가 목표에 맞게 잘 식별되었는지 평가하며 서비스 관계를 도식화하고, 서비스 간의 API와 Pub/Sub 등 어떤 통신 방식을 적용할지 고민한다.
이해관계자 간의 상호 검증을 통해 서비스 분리, 통합 방안을 확인하는 것이 끝났다면, 목표한 설계대로 서비스를 설계하여 MSA를 구축한다.
서비스 설계는 MSA의 장점을 살리기 위해 서비스의 독립성이 확보되는지, 장애가 발생되었을 때 잘 격리 되는지, 유연성있게 확장할 수 있는지, 각 서비스별 배포가 잘 이루어질 수 있는지를 염두에 두고 진행해야한다.
또한 개별 서비스의 내부를 설계하기 전에 API를 우선 정의하여 각 서비스 간의 원활한 호출과 독립적인 동작을 보장하는 API 우선 설계(API First Design) 방식으로 진행하는 것이 좋다. API, Pub/Sub, 데이터 인터페이스를 먼저 정의한다.
MSA에서 여러 서비스에 걸쳐 데이터를 조회하는 로직은 잦은 API 통신과 데이터 조합 작업으로 인해 성능 이슈가 발생할 수 있다. 이런 경우에는 API Composition이나 CQRS 패턴을 활용하는 것이 효과적이다.
API Composition
MSA에서 서비스 간 API 호출이 너무 잦은 경우, 이로 인해 오버헤드가 발생한다.
마지막으로 서비스 설계 시 비동기 이벤트 방식으로 독립성을 확보하고, 완결성 있는 트랜잭션 처리를 고민해야한다.