MSA란 Micro Service Architecture의 약자로, 기존 Monolithic Architecture와 상반된 개념이다. MSA를 알아보기에 앞서 Monolithic Architecture를 알아보자.
하나의 서비스 또는 어플리케이션이 하나의 거대한 아키텍처를 가질 때, Monolithic 하다고 한다.
이 정의를 고려해보자면 애플리케이션의 FE, BE의 서비스가 하나의 서버에서 동작하는 방식도 Monolithic 이지만, 각 서비스의 규모가 거대해진 경우도 Monolithic에 해당한다.
많은 서비스를 하나의 서버에서 실행하는 것은 구조가 심플하고, 애플리케이션의 설계 및 테스트가 용이하다. 무엇보다 트랜잭션을 관리하는 것이 매우 쉽다는 장점이 있다.
하지만 다음과 같은 문제점이 존재한다.
- 하나의 서비스 장애가 전체적인 장애를 야기한다.
- 배포 및 재배포에 많은 비용이 발생한다.
- 의존관계의 모든 서비스를 개발자가 모두 이해해야 한다.
- 기술, 언어, 프레임워크의 선택이 제한적이다.
이러한 MA의 단점을 보완하기 위해 MSA가 도입된다.
MSA는 각 서비스가 작고 독립적으로 배포 가능한 단위로 구성된 구조이다.
하나의 애플리케이션의 서비스가 각각 독립적으로 개발 및 배포되며 각 서비스들은 API를 통해 통신한다.
- 독립적인 개발과 운영이 가능하여 애플리케이션의 확장이 용이하다.
- CI/CD 프로세스에 최적화 되어있다.
- 서비스 단위로 스케일링이 가능하여 물리적인 비용을 절감한다.
- 각 서비스에 적합한 기술과 프레임워크를 적용할 수 있으며 독립적으로 배포가 가능하다.
- 작은 단위로 분리된 서비스의 설계를 잘 고려해야하며, 관리해야 하는 서비스의 수가 늘어난다.
- 서비스 별로 자체 DB를 이용하기도 하며 트랜잭션 관리가 어렵다.
- 애플리케이션의 통합 테스트가 어렵다.
이러한 한계점을 위해 사용하는 기술 중 하나로 Spring Cloud가 있다.
MSA 환경에서는 각 서비스가 독립적으로 관리되며 배포 및 재생성이 빈번하게 발생한다. 만약 컨테이너 환경이 적용된다면 이러한 경향을 더 클 것이다.
또한 스케일링이 이루어지고 로드밸런싱 또한 적용할 수 있다.
Spring Cloud는 위에서 언급했듯이 MSA 환경에서 애플리케이션을 쉽게 개발하고 각 서비스를 배포, 운영하기 위해 사용한다.
Spring Cloud에 주로 사용되는 OSS(Open Source Software)를 보유한 Netflix의 Spring Cloud 기술을 위주로 Spring Cloud의 핵심 컴포넌트를 소개한다.
MSA의 각 마이크로서서비스들에 대한 단일화된 엔드포인트를 제공하는 API-Server이다.
또한 인증, 모니터링, 오케스트레이션, 사용량 제어, 요청/응답 등의 기능을 포함한 향상된 Reverse Proxy 의 역할을 한다.
MSA 내부에서의 각 서비스 간의 요청은 API-Server에게 전달된다. 즉 모든 서비스에 대한 요청을 대신 받아 라우팅한다.
API-Server는 Discovery Server의 Client로서 요청의 대상이 될 서비스의 위치를 Discovery Server에게 요청한다. 응답받은 서비스에게 요청을 전달하고 응답을 반환한다.
Spring Cloud Gateway 서버 라우팅의 가장 기본적인 단위이다.
spring:
cloud:
gateway:
routes:
- id: after_route
uri: https://example.org
predicates:
- Cookie=mycookie,mycookievalue
filters:
- name: CircuitBreaker
args:
name: myCircuitBreaker
fallbackUri: forward:/inCaseOfFailureUseThis
- RewritePath=/consumingServiceEndpoint, /backingServiceEndpoint
route를 구성하는 요소로는 크게 Predicate와 Filter가 있다.
Predicates는 요청을 처리할 route를 선별하는 조건이다. Gateway Handler Mapping 단계에서 수행되며, 보통 요청의 URI, Header, Cookie와 같은 HTTP spec 정보를 이용하여 조건을 설정한다.
filters는 요청의 전후처리를 위해 이용되는 설정이다. filtrer는 크게 GlobalFilter, PreFilter, PostFilter로 나뉜다.
보통 filter를 통해 인증, 로깅, 모니터링을 위해 필요한 로직을 수행한다.
Discovery Server는 MSA의 서비스들의 목록와 위치(IP, Port)를 관리하는 서버이다.
MSA에서 여러 서비스를 운용하기 위해 클라우드 환경, 또는 컨테이너 환경에서 서비스를 구축할 가능성이 높다.
따라서 각 인스턴스는 빈번하게 생성, 삭제, 확장이 이루어질 것이다.
이 때 마다 수많은 서비스의 정보와 변경사항을 관리하는 것은 매우 어려울 것이고, 동적으로 변경되는 서비스에게 요청을 보내기 위해서는 매번 그 서비스의 위치를 관리해주어야 한다.
이를 위해 사용되는 것이 Discovery Server이다.
MSA의 각 마이크로서비스들은 생성시에 자신의 정보(IP,FQDN,PORT 등)를 Discovery-server에 등록한다.
각 서비스들은 주기적으로 자신의 상태를 Discovery Server에게 알리고, 정지된 경우 Discovery Server가 해당 서비스를 서비스 registry에서 삭제한다.
마이크로서비스에게 요청을 전달하기 이전, 해당 서비스의 위치정보를 확인하기 위해 Discovery Server를 거치게 된다.
보통 MSA 환경에서는 Gateway 서버가 routing 할 서비스의 위치를 확인하기 위해 Discovery Server를 조회한다.
Config Server는 MSA 환경에서 서비스들의 설정값을 관리하게 위해 사용되는 서버이다.
Spring을 통해 개발한 서비스의 설정 정보를 런타임 시에 제공할 수 있다. 서비스는 사용되는 설정 정보를 config server에게 요청한다.
Config Server는 설정 정보들이 저장된 저장소에 접근하고 보통 Git Repository가 이용된다.
설정정보가 git을 통해 관리되기 때문에 버전을 추적하고, 특정 시점으로의 롤백 상황에서 용이하다.
애플리케이션에 적용될 설정 정보가 동적으로 변경되어야 한다면 개발자는 git repository에 변경 사항을 적용한다.
변경이 적용될 서비스의 /actuator/refresh 엔드포인트 호출을 통해 설정 정보를 동적을 변경할 수 있다.
(동적으로 변경이 될 빈들은 @RefreshScope 설정이 적용되어 있어야 함)
Spring Cloud 환경에서 시스템의 장애상황을 다루고 가용성을 확보하기에 용이한 라이브러리이다.
https://github.com/resilience4j/resilience4j