📌MicroService Architecture
마이크로서비스란 작고, 독립적으로 배포 가능한 각각의 기능을 수행하는 서비스로 구성된 프레임워크. 단일 프로그램을 각 컴포넌트 별로 나누어 작은 서비스의 조합으로 구축하는 방법. 하나의 큰 애플리케이션을 특정 목적을 가진 애플리케이션 단위(서비스)로 나누어 변경과 조합이 가능하도록 만든 형태를 말한다.
📌기존에 어떤 방식을 방식을 사용했을까? Monolithic Architecture
Monolithic은 ‘하나로 단단히 짜여있는’이라는 뜻으로
Monolithic Architecture란, 소프트웨어의 모든 구성요소가 한 프로젝트에 통합되어있는 형태이다.
출처) https://bambooagile.eu/insights/monolith-vs-microservices/
즉, 위의 그림처럼 Monolithic은 단 하나의 상자라면 Microservice는 그 상자를 잘게 쪼갠 것이라 생각하면 된다.
📖Monolithic Architecture를 사용해왔던 이유
Monolithic Architecture은 전체 애플리케이션이 하나로 되어있어서
- 동일한 개발 툴을 사용해 개발되며,
- 배포 및 테스트도 하나의 애플리케이션만 수행하면 되기 때문에 개발 및 환경설정이 간단하다.
- 또한, 각 컴포넌트들이 함수로 호출 되기 때문에 성능에 제약이 덜하고,
- 운영 관리가 용이하다.
하지만, 시스템이 커지고 여러 컴포넌트가 더해지면 문제가 발생한다.
📖Monolithic Architecture의 문제점
- 부분 장애가 전체 서비스의 장애로 확대될 수 있다.
- 개발자의 잘못된 코드 배포 또는 갑작스런 트래픽 증가로 인해 성능에 문제가 생겼을 때, 서비스 전체의 장애로 확대될 수 있다.
- 부분적인 Scale-out이 어렵다.
- Monolithic Architecture에서는 사용되지 않는 다른 모든 서비스가 Scale-out되어야 하기 때문에 부분 Scale-out이 어렵다. 즉, 이벤트로 인해 서비스 접속 량이 폭증할 경우 프로젝트 전체를 확장해야만 한다.
- 서비스의 변경이 어렵고, 수정 시 장애의 영향도 파악이 힘들다.
- 여러 컴포넌트가 하나의 서비스에 강하게 결합되어 있기 때문에 수정에 대한 영향도 파악이 힘들다.
- 배포 시간이 오래 걸린다.
- 최근 어플리케이션 개발 방법은 CI/CD를 통한 개발부터 배포까지 빠르게 반영하는 추세이다. 그러나 규모가 커짐에 따라 작은 변경에도 높은 수준의 테스트 비용이 발생하기도 하며, 많은 사람이 하나의 시스템을 개발하여 배포하기 때문에 영향을 줄 수 밖에 없다.
- 한 Framework와 언어에 종속적이다.
- Spring framework를 사용할 경우, blockchain 연동 모듈을 추가할 때 node.js를 사용하는 것이 일반적이며 강세이다. 그러나 java를 이용하여 해당 모듈을 작성할 수 밖에 없다. 선정했던 framework가 Spring이기 때문이다.
📌MSA의 등장배경
마이크로서비스 아키텍처가 많이 언급된 시점은 넷플릭스, 아마존, 우버, 이베이와 같은 대형 테크 기업들이 자사의 시스템에 사용하고 이를 널리 전파 하면서 부터이다. 기존의 Monolithic Architecture는 하나의 애플리케이션이 하나의 단일 시스템에 모든 기능과 시스템 컴포넌들을 담아 운영하는 구조로 각 기능은 강결합(strongly coupled) 상태로 연결하여 작은 기능 하나를 추가하더라도 전체 애플리케이션의 레이어들을 모두 다시 테스트하고 배포하는 번거로움이 있다. 작은 단위 기능을 수정했더라도 전체 레이어를 다시 빌드 및 패키징하여 서버를 재기동해야 하기 때문에, 빠른 기능별 개발과 단위 서비스 적용 및 365일 무중단 서비스를 해야 하는 대용량 웹 기반 서비스에 적용하기에 알맞지 않았다.
📌MSA의 특징은?
- 각 컴포넌트는 서비스 형태로 구현되고 API를 이용하여 타 서비스와 통신한다. 서비스의 end-point(접근점)을 API 형태로 외부에 노출하고, 실질적인 세부 사항은 모두 추상화한다. 내부의 구현 로직, 아키텍처와 프로그래밍 언어, 데이터베이스, 품질 유지 체계와 같은 기술적인 사항들은 서비스 API에 의해 철저하게 가려진다. 각 컴포넌트들이 함수로 호출했던 것이 Network I/O 호출로 바뀌게 된다.
- 각각의 서비스는 크기가 작을 뿐, 서비스 자체는 하나의 Monolithic Architecture와 유사한 구조를 가진다.
- 서비스별 최적화된 기술을 독립적으로 사용 가능하다.
- 각각의 서비스는 다른 서비스에 대한 의존성이 최소화 되어야 한다.
→ 따라서 부분적인 확장 가능하다. 이는 메모리, CPU적으로 상당부분 이득이 된다.
- 독립된 서버로 타 컴포넌트와 의존성이 없기 때문에 각각의 서비스는 독립적으로 배포가 가능하다.
→ 배포 시 전체 서비스의 중단이 없다.
- 각 서비스는 개별 프로세스로 구동되며, REST같은 가벼운 방식으로 통신되어야 한다.
📖데이터 분리
데이터 저장 시 하나의 DB에 중앙 집중화를 하지 않고 서비스 별 별도의 데이터 베이스를 사용한다. DB의 종류를 별도로 가져갈 수도 있고, 같은 DB를 사용하더라도 나누어서 사용하게 된다. 데이터가 여러 서비스에 걸쳐 분산되기 때문에 한번에 조회하기 어렵고, 데이터의 정합성 또한 관리하기 어렵다. 또한, 데이터 분산으로 다른 서비스 컴포넌트에 대한 의존성이 없이 서비스를 독립적으로 개발 및 배포/운영 할 수 있지만, 다른 컴포넌트의 데이터를 API통신을 통해 가져와야 하기 때문에 성능상의 문제(통신 비용, Latency 증가)가 발생 할 수 있고, 트렌젝션으로 묶을 수 없는 문제가 발생(join도 어려움)하기도 한다.
→ 규모가 커질 수록 관리할 것도 많아지고 복잡도도 엄청날 것이라는 것!