MSA 구조를 사용하는 회사들이 늘어나고 있는 것 같습니다.
이에 MSA의 기본 개념은 무엇인지 공부해보려 합니다.
마이크로서비스란 무엇인가?
먼저 전통적인 시스템 구조인 모노리스(Monolith) 구조부터 살펴보자. 모노리스는 하나의 단위로 개발되는 일체식 애플리케이션이다. 그림 1과 같이 보통 3티어라 불리는 사용자 인터페이스와 데이터베이스, 서버 쪽 애플리케이션 3개 부분으로 구성된다.
티어: 보통 티어(tier)는 서버와 같은 물리적인 분리를, 레이어(layer)는 논리적인 분리를 말한다. 하나의 티어 내부를 여러 개의 논리 레이어로 나눌 수 있다.
서버 측 애플리케이션이 일체, 즉 논리적인 단일체로서 아무리 작은 변화에도 새로운 버전으로 전체를 빌드해서 배포해야 한다. 그리고 일체식 애플리케이션은 단일 프로세스에서 실행된다. 따라서 확장이 필요한 경우 마이크로서비스 기반 시스템을 나타낸 그림 2처럼 특정 기능만 확장할 수 없고 반드시 전체 애플리케이션을 동시에 확장해야 한다.
보통 로드 밸런서를 앞에 두고 여러 인스턴스 위에 큰 덩어리를 복제해 수평으로 확장한다.
이런 상황에서 변경이 발생하면 모노리스 시스템의 단점이 극대화된다. 즉, 여러 개의 모노리스가 수평으로 확장된 상태이므로 여러 개의 모노리스 시스템 모두를 전부 다시 빌드하고 배포해야 한다. 또한 확장 시 애플리케이션이 병렬로 확장되어 사용량 증가에 대응할 수 있지만 데이터베이스는 통합되어 하나이므로 탄력적으로 대응할 수 없다. 따라서 사전에 성능을 감당하기 위해 스케일 업을 통해 용량을 증설해야 한다.
반면 마이크로서비스는 서버 측이 여러 개의 조각으로 구성돼 각 서비스가 별개의 인스턴스로 로딩된다.
즉, 여러 서비스 인스턴스가 모여 하나의 비즈니스 애플리케이션을 구성한다. 또한 각기 저장소가 다르므로 업무 단위로 모듈 경계가 명확하게 구분된다. 따라서 확장 시에는 특정 기능별로 독립적으로 확장할 수 있고, 특정 서비스를 변경할 필요가 있다면 해당 서비스만 빌드해서 배포하면 된다. 또 각 서비스가 독립적이어서 서로 다른 언어로 개발하는 것도 가능하므로 각 서비스의 소유권을 분리해 서로 다른 팀이 개발 및 운영할 수 있다.
그림 2을 보면 각기 서비스가 분리되어 별도의 저장소를 가지고 있고, 서비스 C의 확장이 필요하면 서비스 C만 스케일 아웃하면 된다.
마이크로서비스는 여러 개의 작은 서비스 집합으로 개발하는 접근 방법이다. 각 서비스는 개별 프로세스에서 실행되고, HTTP 자원 API 같은 가벼운 수단을 사용해서 통신한다. 또한 서비스는 비즈니스 기능 단위로 구성되고, 자동화된 배포 방식을 이용하여 독립적으로 배포된다. 또한 서비스에 대한 중앙 집중적인 관리는 최소화하고, 각 서비스는 서로 다른 언어와 데이터, 저장 기술을 사용할 수 있다.
- 마틴 파울러
그림 3은 마틴 파울러가 정의한 마이크로서비스 개념을 표현한 개념도이다.
각 서비스와 저장소는 다른 서비스 및 저장소와 격리돼 있으며, API를 통해서만 느슨하게 연계된다. 따라서 독립적으로 확장 가능하고 하나의 서비스만 독립적으로 배포 가능하다. 또한 다른 서비스와 연계된 API에 영향을 주지 않는다면 내부의 언어나 저장소는 자율적으로 선택할 수 있다. 그림을 보면 한 서비스에는 자바와 오라클을, 다른 서비스에는 Node.js와 마리아DB(MariaDB)를 선택한 것을 볼 수 있다.
이처럼 특정 서비스를 구축하는 데 사용되는 언어나 저장소를 자율적으로 선택할 수 있는 방식을 가리켜 '폴리글랏(Polyglot)하다'라고 표현한다.
MSA의 모듈화 방식
- 서비스별 저장소를 분리해서 다른 서비스가 저장소를 직접 호출하지 못하도록 캡슐화한다. 즉, 다른 서비스의 저장소에 접근하는 수단은 API밖에 없다.
- REST API 같은 가벼운 개방형 표준을 사용해 각 서비스가 느슨하게 연계되고 누구나 쉽게 사용할 수 있다.
API: 프로그램들이 서로 상호작용하는 것을 도와주는 매개체
경험
그림 4는 제가 경험했던 MSA 구조를 그린 것입니다. 각 서비스는 서버로 구성되어 있으며 데이터 베이스는 MySQL과 Redis를 사용했습니다. 각 서비스는 독립되어 타 서비스에 영향을 주지 않고 배포가 가능합니다.
서비스가 자바, 파이썬, 저장소는 Redis, MySQL을 선택적으로 사용한 것으로 마이크로서비스를 폴리글랏하게 구성했다고 생각합니다.
데이터베이스와 연동하는 서비스가 다수이지만 SNS를 스크랩하는 서버의 경우는 필요가 없고 요청한 서버에 응답만 해주면 됩니다.
알림 서버는 Email, SMS, KakaoTalk을 사용자에게 발송하고 푸시 서버는 사용자 앱에 푸시를 발송합니다.
클라이언트가 직접 알림, 푸시 서버에 API를 호출하는 것이 아닌 Rest, 결제 서버에서 API를 호출합니다.
모노리스 구조와 MSA를 둘 다 경험해봤습니다. 저의 경우 MSA가 더 운영적인 면에서는 좋다고 생각합니다.
특정 기능의 배포 및 에러가 다른 서비스에 영향을 미치지 않고 독립적이니까요. 하지만 여러 서비스가 동시에 배포가 돼야하는 경우가 있을 수 있습니다. 이럴 때는 서비스 서버가 여러 개라면 누락되는 서버없이 모두 배포가 이루어줘야 합니다. 저는 여러 서비스를 동시에 배포해야 하는데 한 서버를 배포하지 못해 버전문제로 화면단에 문제가 생겼던 기억이 있습니다;;
모노리스의 경우 화면과 API가 같은 프로젝트에 있으니 누락되는 서비스없이 같이 배포가 된다는 점은 편리하지만, 장애 및 서비스 배포가 전체 서비스에 영향을 미친다는 점이 단점이라고 생각합니다.
MSA의 경우 서버의 대수가 늘어나는 만큼 서버 비용이 모노리스보다 많이 들수도 있다고 생각이 듭니다만
어떤 기술이든 일장일단이 있다고 생각됩니다.
참고
- 도서: 도메인 주도 설계로 시작하는 마이크로서비스 개발
'[개발] Infrastructure > Deployment' 카테고리의 다른 글
Hystrix (0) | 2023.11.30 |
---|---|
사가 패턴 (0) | 2023.11.27 |
카나리아 배포 (0) | 2023.11.17 |
Docker 블루-그린 배포 (0) | 2023.11.17 |
MSA 통신 패턴 (동기, 비동기)과 Apache Kafka, Zookeeper (0) | 2022.02.27 |