저는 현재 진행중인 간단한 게시판 도메인 개인 프로젝트가 있습니다.
현재의 프로젝트 아키텍쳐는 Monolithic 아키텍쳐입니다.
Monolithic 아키텍쳐에서 MSA로의 전환을 경험해보고 싶어서 개인 프로젝트에 적용하고자 합니다!
개인 프로젝트인만큼 엄~청나게 규모가 작지만 작은 상태에서 전환해보고 그 이후 MSA에서 확장도 시간이 되면 경험해보려고 합니다!
실전에 들어가기 전에, 간략하게 Monolithic 아키텍쳐와 MSA 아키텍쳐가 무엇인지 이론적으로 먼저 알아보겠습니다.
개인 프로젝트에 적용하는 만큼 제 개인 프로젝트에 빗대어서 설명을 해보겠습니다!
개인 프로젝트 ERD는 다음과 같습니다.
정말 단순한 게시판 서비스로, Member 서비스와 Board 서비스 2가지 도메인의 서비스만 존재합니다.
1. Monolithic Architecture란?
제 개인 프로젝트나 사용자가 적은 간단한 서비스 애플리케이션 같은 경우에는 모든 소스 코드가 하나의 Application에 통합되어 빌드되고 배포되는 경우가 많습니다.
이러한 아키텍쳐를 Monolithic Architecture라고 합니다!
현재 개발한 개인 프로젝트가 모놀리식 아키텍쳐라고 할 수 있는데, 이를 도식화하면 아래와 같습니다.
현재 애플리케이션에는 Member, Board 도메인이 존재하고 하나의 Application 안에서 강한 결합을 가지며 존재합니다.
또한 DB 같은 경우도 하나의 Application 안에서 하나의 DB로 관련 도메인의 테이블을 가지고 데이터를 저장합니다.
여기서 초점을 맞춰야 하는 부분은
'하나의 Application 안에서 모든 도메인과 도메인 DB가 강하게 결합되어 있다'는 부분입니다.
이러한 강결합에 의해서 모놀리식 아키텍쳐의 단점이 드러나게 됩니다.
1-1. Monolithic Architecture의 단점
1. 도메인 하나의 장애가 서비스 전체에 영향을 미친다.
위에서 Member, Board 도메인이 존재할 때 게시글 서비스에 트래픽이 몰려서 장애가 발생한다고 가정해봅시다.
이때, 게시글 서비스에 장애가 발생하면 전체 Application에 장애가 발생하여 회원 서비스에도 장애가 발생하게 됩니다.
게시글 관련 문제인데, 회원 관련 기능(회원가입, 로그인 등)을 이용하는 사용자까지 서비스를 이용할 수 없게 되는 것입니다.
2. 각 도메인의 유지보수가 어렵다.
도메인들이 서로 하나의 Application 안에서 강하게 결합되어 있기 때문에,
하나의 도메인 기능을 수정하고 유지보수할 때 해당 도메인뿐만 아니라 연관된 다른 도메인까지 포함하여 고려해야합니다.
따라서 도메인 하나를 유지보수할 때 고려해야 할 사항이 늘어나고, 이후에 다른 도메인에 미칠 영향을 파악하기가 어렵습니다.
3. 빌드 및 배포 시간이 길어서 생산성이 낮아진다.
이 부분은 여러 컨퍼런스의 MSA 관련 발표를 들었을 때 모놀리식의 생산성 측면의 단점으로 꼽히는 것을 볼 수 있었습니다.
여러 서비스가 하나의 Application에 존재하기 때문에 빌드 및 배포 시간이 직렬적으로 처리되어 상대적으로 엄청 깁니다.
또한 이러한 구조에서 서비스가 확장될수록 빌드 및 배포 시간도 따라서 증가하게 됩니다.
이런 부분이 실무의 서비스 생산성 측면에서 상당히 좋지 않다고 합니다.
4. 특정 도메인만 Scale-out 하기가 힘들다.
애플리케이션의 성능을 측정했을 때 특정 도메인 관련 서비스에 트래픽이 몰리는 경우가 많을 것입니다.
제 개인 프로젝트인 게시판 서비스라면, 회원 기능보다는 게시판 기능에 트래픽이 몰릴 것입니다.
이러한 상황에서 Scale-out하여 서버를 늘릴 때 트래픽이 몰리는 서비스만 있는 Application이 아닌
하나의 통합된 Application이 통째로 배포가 되므로 비효율적입니다.
이러한 단점을 극복하기 위해 MSA 아키텍쳐가 등장하게 됩니다.
2. MSA(Micro Service Architecture)란?
MSA는 Micro Service Architecture의 약자로, 쉽게 말하면 다음과 같이 설명할 수 있습니다.
서비스(도메인)별로 독립적인 애플리케이션 환경에서 개발/배포되는 아키텍쳐
위에서 설명했던 모놀리식 아키텍쳐는 하나의 Application 안에서 여러 서비스(도메인)가 통합되어 있는 구조였습니다.
MSA는 이와 반대로 여러 서비스(도메인)가 각각 독립적으로 구성되어 있는 구조입니다.
이를 도식화하면 다음과 같습니다.
이렇게 도메인별로 Member Application, Board Application으로 나누어서 개별적으로 개발/배포가 되는 아키텍쳐입니다.
Application이 나뉘면서 도메인과 DB가 분리된 모습을 확인할 수 있습니다.
MSA에서 추가되는 개념들이 많지만, 아키텍쳐 구조에서 보이는 것은 'API Gateway'라는 구성 요소가 추가된 것을 볼 수 있습니다.
API Gateway는 쉽게 말하면 외부의 요청을 받아서 알맞는 도메인 Application에게 요청을 보내는 MSA 구성 요소입니다.
모놀리식 아키텍쳐에서는 Application이 하나였기 때문에 외부의 요청을 하나의 Application에서 처리하면 됐었습니다.
하지만 MSA에서는 Application이 도메인별로 나뉘기 때문에
외부의 요청이 어떤 도메인 관련 요청인지 판단해서 해당 Application에게 처리하도록 전달하는 단계가 하나 추가되어야 합니다.
이러한 단계에서 작업을 처리하는 구성 요소가 API Gateway입니다.
(API Gateway 이외의 MSA 구성 요소도 많지만, 이와 관련해서는 다음 포스팅에서 다뤄보도록 하겠습니다.)
2-1. MSA의 장점(모놀리식 아키텍쳐의 단점 보완)
모놀리식 아키텍쳐에서 MSA 아키텍쳐로 구조를 변경하면서 모놀리식 구조의 단점들을 보완할 수 있습니다.
1. 도메인 하나의 장애가 서비스 전체에 영향을 미친다. -> 도메인 하나의 장애가 서비스 전체에 전파되지 않는다.
이전의 모놀리식 아키텍쳐에서는 도메인 하나의 장애가 서비스 전체에 영향을 미쳤었습니다.
앞에서 든 예시인 Member, Board 도메인이 존재할 때 게시글 서비스에 트래픽이 몰려서 장애가 발생하는 상황을 생각해봅시다.
여기서 MSA에서는 Member와 Board Application이 분리되어 있기 때문에 Board Application의 장애는
Member Application에게 전파되지 않습니다.
따라서 게시글 서비스에 장애가 발생하더라도 회원 기능(회원 가입, 로그인 등)은 정상적으로 동작하게 됩니다.
2. 각 도메인의 유지보수가 어렵다. -> 상대적으로 각 도메인의 유지보수가 쉽다.
이전의 모놀리식 아키텍쳐에서는 도메인 간 강결합을 가지기 때문에 유지보수가 어려웠습니다.
하지만 MSA 아키텍쳐는 서비스가 독립적으로 구성되기 때문에 도메인의 유지보수가 상대적으로 쉬워집니다.
3. 빌드 및 배포 시간을 줄여서 생산성을 높일 수 있다.
이전의 모놀리식 아키텍쳐에서는 기본적으로 빌드 및 배포가 직렬적으로 구성되어 소요 시간이 길었습니다.
또한 새로운 도메인이 추가될 때마다 선형적으로 빌드 및 배포 시간이 길어지는 단점이 있었습니다.
MSA에서는 서비스가 독립적으로 구성되기 때문에 동시에 병렬적으로 여러 서비스 빌드 및 배포가 가능합니다.
우선 모놀리식 아키텍쳐에서는 두 상황 모두 동일하게 여러 서비스가 포함된 하나의 Application을 빌드 및 배포해야 했습니다.
모놀리식 아키텍쳐에서 Member, Board 서비스를 빌드하는 시간을 각각 10초라고 했을 때 총 20초가 걸리게 됩니다.
여기서 MSA는 Member, Board Application을 동시에 빌드할 수 있기 때문에 빌드 시간이 10초로 훨씬 줄어들게 됩니다.
(물론, 정확하게 10초가 걸리진 않겠지만 이해를 위해 가정했습니다!)
현재 개인 프로젝트의 규모가 적어서 2가지 도메인밖에 존재하지 않지만 규모가 커서 여러 도메인이 존재한다면
모놀리식 아키텍쳐에서의 빌드 시간은 선형적으로 급증하는 반면에, MSA에서의 빌드 시간의 증가폭은 훨씬 적을 것입니다.
4. 특정 도메인만 Scale-out 하기가 힘들다. -> 도메인별로 Scale-out이 쉽다.
이전의 모놀리식 아키텍쳐에서는 여러 서비스가 하나의 Application에 통합되어 있었기 때문에
특정 도메인의 서버만 Scale-out 하기가 힘들었습니다.
MSA에서는 서비스가 독립적으로 분리되어 있기 때문에 도메인별로 Scale-out을 쉽게 할 수 있습니다.
만약 게시글 기능에 트래픽이 많다면 회원 서버는 1대로 운영한 채로 게시글 서버를 2, 3대로 Scale-out하여 운영할 수 있습니다.
2-2. MSA 전환 시 추가적으로 고려할 점
앞서 장점을 살펴봤는데 모놀리식 아키텍쳐에서 MSA로 전환 시 추가적으로 고려할 점들도 존재합니다.
간략하게 살펴만 보고 시간이 된다면 이후 포스팅에서 적용한 경험을 다뤄보겠습니다!
1. 외부의 요청을 알맞는 서비스 Application에 어떻게 전달할 것인가?
모놀리식 아키텍쳐에서는 하나의 Application만 존재했기 때문에 모든 요청이 하나의 Application에 전달되면 됐었습니다.
MSA에서는 도메인별로 Application이 분리되었기 때문에 외부 요청에 대한 도메인 분기 처리가 필요해지게 되었습니다.
이러한 처리를 MSA에서는 API Gateway 개념을 도입하여 해결할 수 있습니다.
2. 서비스(도메인) 간 통신을 어떤 방식으로 할 것인가?
모놀리식 아키텍쳐에서는 하나의 Application 안에 여러 서비스가 강결합을 맺고 있었습니다.
그래서 비즈니스 로직 상 도메인 간의 참조가 필요하다면 애플리케이션 코드 단에서 직접 참조하여
추가적인 리소스 없이 다른 도메인의 정보를 가져올 수 있었습니다.
예를 들면, 게시글 조회 기능에서 게시글 작성자 정보를 가져올 때 모놀리식에서는 Board 엔티티에서 직접적으로
멤버 정보를 가지고 있거나, 아니면 Application 안의 멤버 DB를 통해 멤버 정보를 가져올 수 있었습니다.
하지만 MSA에서는 Member Application과 Board Application이 분리되었기 때문에 게시글 관련 기능에서
멤버 관련 정보를 가져오기 위해서는 추가적인 리소스로 Member Application에 요청을 보내야 합니다.
이렇게 추가적인 리소스로 다른 서비스와의 통신을 하는 방식은 크게 다음과 같습니다.
- RestTemplate
- WebClient
- OpenFeign
- 메시지 브로커 (Kafka, RabbitMQ, ActiveMQ 등)
이 중에서 적절한 방식을 골라서 서비스 간 통신을 하면 됩니다.
3. 하나의 기능에서 트랜잭션을 어떻게 유지해야 할 것인가?
모놀리식 아키텍쳐에서는 하나의 Application에 여러 테이블이 존재하는 통합 DB를 구성하여 데이터를 저장 및 조회했습니다.
MSA에서는 각 서비스가 분리됨에 따라서 DB 또한 도메인별 DB로 분리됩니다.
이렇게 DB가 분리됨에 따라서 하나의 기능에 대한 트랜잭션 관리가 힘들어집니다.
예를 들면, 게시글 작성 시 Board 테이블 뿐만 아니라 멤버 정보를 가져오기 위해 Member 테이블을 조회하는 상황일 때
모놀리식 아키텍쳐는 하나의 DB에 Member, Board 테이블이 존재하기 때문에 하나의 트랜잭션으로 묶을 수 있었습니다.
그러나 MSA에서는 Member DB, Board DB로 나뉘어지기 때문에 일반적으로는 하나의 트랜잭션으로 묶기가 어렵습니다.
따라서 Member DB에서 장애가 발생했을 때 Board DB를 롤백하기가 쉽지 않습니다.
이러한 문제를 해결하기위한 트랜잭션 패턴은 크게 다음과 같이 2가지가 존재합니다.
- 2PC 패턴(Two-Phase Commit)
- Saga 패턴
이러한 패턴을 사용하여 하나의 기능에 대해 트랜잭션을 관리할 수 있습니다.
4. 서비스들의 정보를 어떻게 관리할 것인가?
앞서 MSA에서는 외부에서 오는 요청은 API Gateway를 통해서 전달되고, 서비스 간 통신도 이루어진다고 했습니다.
이때 API Gateway는 어떻게 서비스 Application의 정보를 알아서 전달하고,
각 서비스들도 어떻게 다른 서비스 Application의 정보를 알아서 통신할까요?
간단히 생각해보면 API Gateway에서 모든 서비스 Application의 정보를 수동으로 등록하고
각 서비스에서도 다른 서비스들의 정보를 수동으로 등록하면 간단히 해결됩니다.
그러나, 애플리케이션을 운영하다 보면 사용하지 않는 서비스, 추가해야하는 서비스가 있을 수 있습니다.
이렇게 됐을 때 서비스가 확장/축소 될 때마다 수동으로 API Gateway, 각 서비스들의 정보들을 업데이트 해야합니다.
MSA에서는 이러한 과정을 각 서비스들의 정보를 등록/관리하는 서비스 디스커버리 패턴을 통해 처리합니다.
이렇게 크게 MSA 사용 시 고려할 점 4가지를 살펴봤습니다.
물론 MSA가 엄청 복잡해서 이외에도 엄청 고려할 점이 많지만, 대표적으로 고려할 점을 살펴봤습니다.
이번 포스팅은 모놀리식 아키텍쳐와 MSA 아키텍쳐를 간략하게 이론적으로 살펴보게 되었습니다.
이후에는 모놀리식 아키텍쳐인 현재 개인 프로젝트를 MSA로 전환하는 과정을 다뤄보도록 하겠습니다.
📘 Monolithic to MSA 전체 목차
[MSA] 개인 프로젝트 Monolithic to MSA 전환기 - (1) MSA란?
[MSA] 개인 프로젝트 Monolithic to MSA 전환기 - (2) 멀티 모듈 구성하기
[MSA] 개인 프로젝트 Monolithic to MSA 전환기 - (3) Service Discovery 패턴 적용하기(feat. Spring Cloud Eureka)
[MSA] 개인 프로젝트 Monolithic to MSA 전환기 - (4) API Gateway 구현(feat. Spring Cloud Gateway)
[MSA] 개인 프로젝트 Monolithic to MSA 전환기 - (5) 서비스 간 통신하기(feat.Spring Cloud OpenFeign)
[MSA] 개인 프로젝트 Monolithic to MSA 전환기 - (6) 각 서비스의 설정 파일 관리하기(feat. Spring Cloud Config)
[MSA] 개인 프로젝트 Monolithic to MSA 전환기 - (7) 서비스 장애 대응 Circuit Breaker 구현(feat. Resilience4J)
[MSA] 개인 프로젝트 Monolithic to MSA 전환기 - (10) MSA 전환 후 비교 및 회고 + 마무리
Reference
https://enjoy-dev.tistory.com/1
'아키텍쳐' 카테고리의 다른 글
[MSA] 개인 프로젝트 Monolithic to MSA 전환기 - (3) Service Discovery 패턴 적용하기(feat. Spring Cloud Eureka) (2) | 2024.02.03 |
---|---|
[MSA] 개인 프로젝트 Monolithic to MSA 전환기 - (2) 멀티 모듈 구성하기 (1) | 2024.02.02 |
Controller와 Service 레이어 간 요청 & 응답 Dto 사용에 관하여 (2) | 2023.06.19 |
[아키텍쳐] 패키지 구조 : 계층형 VS 도메인형 어떤 것을 선택할까? (4) | 2023.05.06 |
[아키텍쳐] Service, Repository가 왜 필요할까? (0) | 2023.04.24 |