MSA란?
MSA는 소프트웨어 개발 기법 중 하나로, 어플리케이션 단위를 '목적'으로 나누는 것
MSA 배경(Monolithic vs MSA)
모노리틱 아키텍쳐(Monolithic Architecture)
모노리틱 아키텍쳐 스타일은 기존의 전통적인 웹 시스템 개발 스타일로, 하나의 애플리케이션 내에 모든 로직들이 모두 들어 가 있는 “통짜 구조” 이다.
예를 들어, 온라인 쇼핑몰 애플리케이션이 있을때, 톰캣 서버에서 도는 WAR 파일(웹 애플리케이션 패키징 파일)내에, 사용자 관리,상품,주문 관리 모든 컴포넌트들이 들어 있고 이를 처리하는 UX 로직까지 하나로 포장되서 들어가 있는 구조이다.
장점
각 컴포넌트들은 상호 호출을 함수를 이용한 call-by-reference 구조를 취한다.
전체 애플리케이션을 하나로 처리하기 때문에, 개발툴 등에서 하나의 애플리케이션만 개발하면 되고, 배포 역시 간편하며 테스트도 하나의 애플리케이션만 수행하면 되기 때문에 편리하다.
규모가 작은 애플리케이션에서는 배포가 용이하고, 규모가 크더라도, call-by-reference call에 의해서 컴포넌트간 호출시 성능에 제약이 덜하며, 운영 관리가 용이하다.
단점
모노리틱 구조의 경우 작은 크기의 애플리케이션에서는 용이 하지만, 규모가 큰 애플리케이션에서는 불리한 점이 많다.
1. 크기가 크기 때문에, 빌드 및 배포 시간, 서버의 기동 시간이 오래 걸림
2. 한두사람의 실수는 전체 시스템의 빌드 실패를 유발하기 때문에, 프로젝트가 커질 수 록, 여러 사람들이 협업 개발하기가 쉽지 않다.
3. 시스템 컴포넌트들이 서로 로컬 콜 (call-by-reference)기반으로 타이트하게 연결되어 있기 때문에, 개발자가 대략적인 전체 시스템의 구조 등을 이해 해야 하는데, 시스템의 구조가 커질 수 록, 개인이 전체 시스템의 구조와 특성을 이해하는 것은 어려워진다.
4. 특정 컴포넌트를 수정하고자 했을때, 컴포넌트 재 배포시 수정된 컴포넌트만 재 배포 하는 것이 아니라 전체 애플리케이션을 재 컴파일 하여 전체를 다시 통으로 재배포 해야하기 때문에 잦은 배포가 있는 시스템의 경우 불리하다.
5. 컴포넌트 별로, 기능/비기능적 특성에 맞춰서 다른 기술을 도입하고자 할때 유연하지 않다. 예를 들어서, 전체 애플리케이션을 자바로 개발했다고 했을 때, 파일 업로드/다운 로드와 같이 IO 작업이 많은 컴포넌트의 경우 node.js를 사용하는 것이 좋을 수 있으나, 애플리케이션이 자바로 개발되었기 때문에 다른 기술을 집어 넣기가 매우 어렵다.
마이크로 서비스 아키텍쳐(Micro Service Architecture)
마이크로 서비스 아키텍쳐는 대용량 웹서비스가 많아짐에 따라 정의된 아키텍쳐인데, 그 근간은 SOA (Service Oriented Architecture : 서비스 지향 아키텍쳐)에 두고 있다.
SOA는 엔터프라이즈 시스템을 중심으로 고안된 아키텍쳐라면, 마이크로 서비스 아키텍쳐는 SOA 사상에 근간을 두고, 대용량 웹서비스 개발에 맞는 구조로 사상이 경량화 되고, 대규모 개발팀의 조직 구조에 맞도록 변형된 아키텍쳐이다.
마이크로 서비스 아키텍쳐에서는 각 컴포넌트를 서비스라는 개념으로 정의한다. 서비스는 데이타에서 부터 비지니스 로직까지 독립적으로 상호 컴포넌트간의 의존성이 없이 개발된 컴포넌트(이를 버티컬 슬라이싱/Vertical Slicing-수직적 분할이라고 한다.)로 REST API와 같은 표준 인터페이스로 그 기능을 외부로 제공한다.
서비스 경계는 구문 또는 도메인(업무)의 경계를 따른다. 예를 들어 사용자 관리, 상품 관리, 주문 관리와 같은 각 업무 별로 서비스를 나눠서 정의한다. 사용자/상품 관리 처럼 여러개의 업무를 동시에 하나의 서비스로 섞어서 정의하지 않는다.
REST API에서 /users, /products와 같이 주요 URI도 하나의 서비스 정의의 범위로 좋은 예가 된다.
MSA 기능
1. 데이터 분리
중앙 집중화된 하나의 통 데이터 베이스를 사용하는 것이 아니라 서비스 별로 별도의 데이터 베이스를 사용한다.
보통 모노리틱 서비스의 경우에는 하나의 통 데이터 베이스 (보통 RDBMS를 사용) 하는 경우가 일반적이지만, 마이크로 서비스 아키텍쳐의 경우, 서비스가 API에서 부터 데이터 베이스까지 분리되는 수직 분할 원칙 (Vertical Slicing)에 따라서 독립된 데이터 베이스를 갖는다.
2. API Gateway
api gateway는 마치 프록시 서버 처럼 api들 앞에서 모든 api에 대한 end point를 통합하고, 몇가지 추가적인 기능을 제공하는 미들웨어로, SOA의 ESB (Enterprise Service Bus)의 경량화 버전이다.
Apigateway는 MSA에서 EndPoint 통합 및 토폴로지 정리를 한다.
마이크로 서비스 아키텍쳐의 문제점 중의 하나는 각 서비스가 다른 서버에 분리 배포 되기 때문에, API의 End point 즉, 서버의 URL이 각기 다르다는 것이다.
사용자 컴포넌트는 http://user.server.com, 상품 컴포넌트는 http://product.server.com 과 같은 분리된 URL을 사용하는데, 이는 API 사용자 경험 관점에서도 사용하기가 불편하다.
이러한 토폴로지상의 문제점을 해결하기 위해서 중앙에 서비스 버스와 같은 역할을 하는 채널을 배치 시켜서, 전체 토폴로지를 p2p에서 hub & spoke 방식으로 변환 시켜서, 서비스간 호출을 단순화 시킬 수 있다.
3. Orchestration
기존 open api의 mash up과 같은 개념으로, 여러개의 서비스를 묶어서 하나의 새로운 서비스를 만드는 개념이다.
예를 들어, 포인트 적립과, 물품 구매라는 서비스가 있을때, 이 두개의 서비스를 묶어서 “물품 구입시 포인트 적립”이라는 새로운 서비스를 만들어 낼 수 있다. 이러한 orchestration 기능은, api gateway를 통해서 구현될 수 있다.
4. 공통 기능 처리 (Cross cutting function handling)
또한 API에 대한 인증 (Authentication)이나, Logging과 같은 공통 기능에 대해서 서비스 컴포넌트 별로 중복 개발해야 하는 비효율성을 유발할 수 있다. api gateway에서 이러한 공통 기능을 처리하기 되면, api 자체는 비지니스 로직에만 집중을 하여 개발에 있어서의 중복등을 방지 할 수 있다.
등등...
MSA단점
1. 마이크로 서비스 아키텍쳐는 서비스간의 호출을 API 통신을 이용하기 때문에 시간이 더 추가로 소요된다.
2. 각 서비스를 독립된 서버에 분할 배치하기 때문에, 중복되는 모듈에 대해서 그만큼 메모리 사용량이 늘어난다.
예를 들어 하나의 톰캣 인스턴스에서 사용자 관리와 상품 관리를 배포하여 운용할 경우, 하나의 톰캣을 운영하는데 드는 메모리와, 스프링 프레임웍과 같은 라이브러리를 사용하는데 소요되는 메모리 그리고 각각의 서비스 애플리케이션이 기동하는 메모리가 필요하다.
3. 테스팅이 더 어려움
4. 서비스 별로 서로 다른 기술을 사용할 수 있으며, 시스템이 아주 잘게 서비스 단위로 쪼게 지기 때문에 운영을 해야할 대상 시스템의 개수가 늘어나고, 필요한 기술의 수도 늘어나게 되어 운영이 더 어려워진다.
5. 서비스간 트렌젝션 처리.
모노리틱 아키텍쳐에서는 RDBMS를 사용하면서 하나의 애플리케이션 내에서 트렌젝션이 문제가 있으면 쉽게 데이타베이스의 기능을 이용해서 rollback을 할 수 있었다. 여러개의 데이타베이스를 사용하더라도, 분산 트렌젝션을 지원하는 트렌젝션 코디네이터 (JTS – Java Transaction Service)등을 이용해서 쉽게 구현이 가능했는데, API 기반의 여러 서비스를 하나의 트렌젝션으로 묶는 것은 불가능 하다.
예를 들어, 계좌에서 돈을 빼는 서비스와, 계좌에 돈을 넣는 서비스가 있다고 하자. 이 둘은 API를 expose했을 때, 계좌에서 돈을 뺀 후, 계좌에 돈을 넣기 전에 시스템이 장애가 나면, 뺀 돈은 없어지게 된다. 모노리틱 아키텍쳐를 사용했을 경우에는 이러한 문제를 트렌젝션 레벨에서 롤백으로 쉽게 해결할 수 있지만 API 기반의 마이크로 서비스 아키텍쳐에서는 거의불가능하다.
참고