MSA Design Pattern과 Spring Cloud

#MSA#spring cloud

2023-10-16 07:23

대표 이미지

이 글은 Microservice를 구현하기 위해 실질적으로 고려해야될 패턴들을 정리합니다. 원활한 이해를 위해 개념과 특성, Cloud와의 관계에 대해서 짚어가며 설명하니 천천히 읽어보세요!

개요


Microservice라는 개념은 등장한지도, 실무에 적용된지도 매우 오래된 아키텍처 패턴임에도, 여전히 대세로 소개되고 있다. 그 이유는 Cloud 환경으로의 전환이 점점 더 일반화, 가속화되고 있는데 그런 Cloud의 핵심 개념이 Microservice이기 때문이다. 때문에 MSA에 대한 자료 또는 상세 기술 별 솔루션들에 대한 가이드들도 이미 많이 나와있다.

그러나 실질적으로 Microservice를 구현하기 위해 어디서부터 시작해야 할지, 어떤 것들을 해야할지, 어디까지 해야할지에 대해서는 잘 정리되어있지 않아 막막하다. 본 글에서는 그런 온전한 Microservice를 구현하기 위해 실질적으로 고려해야될 패턴들을 정리한다. 그 전에 원활한 이해를 위해 개념과 특성, Cloud와의 관계에 대해서 짚어볼 것이다.

이 글의 대상은 다음과 같다

  • MSA 애플리케이션을 구축해보지 않은 개발자

이 글을 읽고 나면 아래와 같은 것들을 알 수 있다.

  • MSA 개념과 특성
  • MSA를 구축하기 위해 고려하고 개발해야 할 패턴들
  • MSA 패턴별 적합한 Spring Cloud 기술

Microservice의 등장 배경 : Monolith에서 MSA


IT 시장의 요구사항 변화

새로운 기술 패러다임으로 해결하려는 것은 결국엔 비즈니스 요구사항이다. IT 시장이 커짐에 따라 치열해진 경쟁 및 더 고도화된 IT 서비스는 애플리케이션 구축 방식의 변화를 가져왔다.

  • 복잡성 증가 : 한 조직 내의 통합되지 않은 애플리케이션은 더 이상 표준이 아니다. 하나의 애플리케이션에서 다양한 서비스 및 DB와 연동되어 있어야 한다. (e.g. 국민은행 28개의 앱 vs Toss)
  • 빠른 고객 니즈 반영 필요 :  서비스 경쟁력 확보를 위해 빠른 개발 프로세스(접수 → 기획 → 개발 → 테스트 → 배포)가 요구된다.
  • 안정적인 성능과 확장성 요구 : 글로벌 엔터프라이즈 애플리케이션은 언제, 얼마나 많은 트랜잭션 양을 처리해야하는지 예측하기 매우 어렵다. 이에 대해 신속하고 유연하게 대응할 수 있어야 한다.
  • 높은 회복성 필요 : 애플리케이션 규모가 커짐에 따라 단일 이슈가 전체 서비스에 영향이 가지 않도록 제어될 수 있어야 한다.

위의 변화에 대응하기 위해 애플리케이션은 유연성, 확장성, 회복성을 갖춘 아키텍처를 필요로 하게 되었다.

Monolith에서 Microservice로의 진화

Microservice의 개념은 3가지 측면에서 기존 Monolith 방식의 대규모 어플리케이션이 직면한 난제를 해결하기 위해 적용된다.

  • 유연성 : 기존 서비스의 수정 또는 새로운 기능 추가가 쉬운가?
  • 확장성 : 세부 서비스, 기능별로 가용할 수 있는 리소스의 수평 확장/축소가 가능한가?
  • 회복성 : 일부 기능 이슈가 전체 서비스에 영향을 끼치지 않는가?
Monolith Microservice
구조Architecture img_01.png  img_02.png
확장성Scalable 특정 기능에서 병목 현상이 발생해도 전체 애플리케이션의 서버 인스턴스를 확장해야 한다. 분리된 각 서비스의 서버 인스턴스에 대해 개별적으로 수평 확장이 가능하여 리소스 절감이 가능하다.
유연성Flexible 하나의 패키지에 전체 서비스 코드를 관리함에 따라 복잡성이 증가하고 일부 기능 수정에도 전체 서비스에 대한 빌드, 배포를 필요로 한다. 서비스 간 코드 의존성이 없어 코드 변경에 따른 복잡성이 낮고, 기능별 테스트 및 배포 시간이 줄어든다.
회복성Resilient 일부 기능에서 많은 리소스를 소모해가며 에러를 발생시키면 전체 서비스 운영에 영향을 미칠 수 있다. 물리적인 서비스 분리로 인해 일부 기능의 이슈가 전체 서비스 장애로 확대되기 전에 억제할 수 있다.

따라서, 변경이 잦고 서비스 규모가 큰 애플리케이션일수록 Microservice Architecture가 적합하다.

Cloud와 Microservice


Cloud Computing은 Microservice Architecture의 구조적인 특성을 실제 서비스에 반영될 수 있는 기술셋을 제공하는 역할을 한다.

Cloud Computing이란?

유연하고 안전하면서 사용하기 편한 서비스 개발/운영 환경을 위해 가상화된 컴퓨팅 리소스(Memory, Storage, Network, Server, Analytics 등)를 제공하는 것을 의미한다. 이로 인해 사용자에게 낮은 초기 투자 비용, 사용 및 유지 보수 용이성, 확장성을 제공한다. 클라우드 컴퓨팅 모델은 사용자와 클라우드 공급업체 중 누가 컴퓨팅 리소스를 얼마나 담당하는지에 따라 'XaaS' 형태로 구분된다. img_03.png

Microservice 그 자체로는 하나의 Architecture Pattern일 뿐이다. 독립적인 산출물로 패키징되고 배포되는 Microservice의 형태가 최종적으로 물리서버일지, 가상 머신 이미지일지, 가상 컨테이너일지 정해져있지 않다. 그러나 Cloud 플랫폼을 통한 Microservice 구현이 Microservice의 특성을 가장 극대화해주기 때문에 컨테이너의 형태로 사용되고 있으며, MSA에는 Cloud가 필연적인 존재가 되었다.

  • 서버 탄력성 강화 : VM과 Container를 수분 안에 가동할 수 있게 해주어 운영 뿐만 아니라 높은 회복성을 갖게 한다.
  • 운영 관리 간소화 : 간단한 API 호출로 수십~수백개의 Microservice 운영에 필요한 다양한 통제를 할 수 있게 한다.
  • 대규모 수평 확장성 제공 : 빠르고 간결하게 Scale-out을 통해 Microservice별 수평 확장 및 지속적 확장을 가능하게 한다.

Microservice Architecture


Microservice Architecture 구성

img_04.png

Microservice Architecture 패턴

마이크로서비스를 작성하는 것은 쉽지만, 실제 환경에서 완전하게 운영하려면 고려해야할 사항들이 많다. 아래 정리된 마이크로서비스 개발시 우선적으로 고려해야 할 주요 패턴 6가지에 대해 인지하고 있다면, 온전한 마이크로서비스를 구축하는데 이슈는 없을 것이다.

  1. 핵심 개발: 마이크로서비스 구축에 대한 기본적인 서비스 설계 방법
    1. 서비스 분해 : 적정 수준의 책임을 갖도록 비즈니스 도메인을 마이크로서비스로 분해한다.
    2. 통신 프로토콜 : 동기 / 비동기
    3. 인터페이스 설계 : N-tier / Domain Driven Design / ...
    4. 서비스 구성 정보 관리 : phase별 환경 구성 관리 방법
    5. 서비스 간 이벤트 처리 : 이벤트 기반 아키텍처
  2. 라우팅: 외부 클라이언트와 마이크로서비스간의 해당 서비스로 라우팅하는 방법
    1. Service Discovery 패턴 : 클라이언트가 서비스 위치를 동적으로 찾게 하는 방법
    2. Service Routing 패턴 : API Gateway를 통해 모든 서비스에 단일 진입점을 제공하고 여러 마이크로서비스에 대해 일관된 보안 정책과 라우팅 규칙을 적용하는 방법
  3. 회복성: 하나의 서비스 또는 인스턴스에서의 이슈가 전체 서비스로 전파되는 것을 막는 방법
    1. 클라이언트 부하 분산 패턴(Load Balancing) : 서비스 디스커버리에서 조회한 마이크로서비스 엔드포인트를 캐싱하고 서비스 호출이 인스턴스 간에 적절히 분산되도록 하는 방법
    2. 회로 차단기 패턴(Circuit Breaker Pattern) : 실패 중이거나 성능 이슈가 있는 서비스를 계속 호출하지 않도록 하는 방법 → 리소스 자원의 과도한 소비를 막기 위해 빠르게 실패하게 하는 방법
    3. 폴백 패턴(Fallback Pattern) : 마이크로서비스가 실패할 때 다른 수단(대체 경로)으로 서비스 클라이언트에게 안내하는 방법
    4. 벌크헤드(격벽) 패턴(Bulkhead Pattern) : 한 서비스의 오동작이 클라이언트의 모든 자원을 차지하지 않도록 호출을 격리하는 방법
  4. 보안: 마이크로서비스를 보호할 수 있는 인증 서비스를 구축하는 방법
    1. 인증 (Authentication) : 서비스를 호출하는 클라이언트가 누구인지 확인하는 방법
    2. 인가 (Authorization) : 클라이언트의 수행하려는 행동에 대해 수행 자격 여부를 확인하는 방법
    3. 자격 증명 관리 전파 : 클라이언트가 서비스를 호출할 때마다 자격 증명을 제시하지 않는 방법. 토큰 기반의 보안 표준 방법.
  5. 로깅과 추적: 분산된 서비스 추적 구현 방법 (MSA는 동작 하나에 수많은 마이크로서비스 호출이 발생할 수 있어 이슈를 디버깅하고 추적 및 모니터링하기가 훨씬 어렵다.)
    1. 로그 상관관계(log correlation) : 사용자의 한 트랜잭션 내에 포함된 여러 서비스들의 로그를 연결하기 위해 사용하는 패턴. 상관관계 ID를 구현하는 방법
    2. 로그 수집(log aggregation) : 마이크로서비스가 출력한 모든 로그를 질의(query) 가능한 DB로 수집하고 관리하는 방법
    3. 마이크로서비스 추적 : 질의(query)를 통해 트랜잭션을 찾을 수 있는 UI를 제공하는 방법
  6. 빌드/배포: 인프라스트럭처 구성(configuration)을 빌드/배포 프로세스에 통합해서 자바 WAR가 아닌 컨테이너 이미지로 빌드하고 배포하는 방법
    1. CI/CD Pipeline
    2. 코드형 인프라스트럭처 (Infrastructure as Code) (Ansible / Terraform / ...)

Spring Cloud


MSA의 각 패턴들을 처음부터 구현하는 것은 엄청난 작업이 될 것이다.

이를 위해 스프링 팀은 시장에서 검증된 수많은 오픈 소스 프로젝트(VMWare, HashiCorp, Netflix 등)를 모아 Spring Cloud라는 스프링 하위 프로젝트로 통합하였다.

Spring Cloud는 MSA의 각 패턴에 매핑되는 솔루션을 제공하며, 덕분에 Microservice를 만들고 배포하는데 필요한 인프라스터럭처 구성의 세부 사항은 신경쓰지 않고 코드를 작성하는 데만 집중할 수 있다. img_05.png

Spring Cloud Config

  • 마이크로서비스와 분리된 애플리케이션의 환경별 구성 데이터(application.yml)를 관리한다.
  • 별도 Git 레포지토리로 구성 데이터만 모아서 관리될 수 있으며, 환경 설정 업데이트에 대해 무중단으로 적용할 수 있다.

Spring Cloud Eureka Service Discovery

  • 동적인 마이크로서비스 인스턴스가 시작되고 종료될 때 인스턴스 등록 및 제거 처리한다.
  • 서비스의 물리적 위치(IP 및 서버 이름)를 논리적 위치(서비스 이름)로 추상화하여 서비스 소비자에게 제공한다.

Spring Cloud API Gateway

  • 사용자 요청을 Proxying하고 요청을 처리하는 서비스로의 라우팅 기능을 제공한다.
  • 서비스들에 대한 보안 인증, 인가, 컨텐츠 필터링 및 라우팅 규칙 등의 표준 서비스 정책들을 관리한다.

Spring Cloud Stream

  • 경량 메시지 처리 기능을 마이크로서비스에 쉽게 통합하는 기능을 제공한다.
  • RabbitMQ 또는 Kafka와 같은 메시지 브로커와 쉽고 빠르게 연동하여 서비스 간 비동기 이벤트를 처리한다.

Spring Cloud Load Balancer와 Resilience4j

  • Spring Cloud Load Balancer는 Eureka 서비스 디스커버리와 통합하는 것을 단순화하고 서비스 이용자 호출에 대한 부하 분산 기능을 제공한다.
  • Java 기반의 Resilience4j 라이브러리는 회로 차단기, 폴백, 벌크헤드 등 회복성 패턴에 대한 인터페이스 제공을 통해 쉽게 개발할 수 있도록 한다.

Spring Cloud Sleuth

  • 고유한 추적 식별자(상관관계 ID, 트레이스 ID)를 HTTP 요청 및 메시지 채널(RabbitMQ 또는 Kafka 등)에 연동하여 여러 서비스를 통과하는 트랜잭션을 추적할 수 있게 한다.
  • ELK 스택 등의 집계 기술 도구와 Zipkin 등의 추적 도구와 결합하여 모니터링 및 서비스 흐름에 대한 시각화를 구축할 수 있다.

Spring Cloud Security

  • 인증 및 인가 프레임워크로서, Token을 기반으로 각 서비스들에게 사용자 신원과 액세스 권한을 검증할 수 있는 인터페이스를 제공한다.
  • JWT(Json Web Token)을 지원하며, JWT는 OAuth2 토큰 생성 포맷을 표준화하고 생성된 토큰에 대한 서명(Signature)을 정규화한다.

맺음말


Microservice의 특정 기능에 대해서 필요한 기술셋을 검색해서 적용하는 것은 기존에 가이드가 워낙 많이 나와있어서 어렵지 않다.

하지만 정작 처음부터 Microservice 애플리케이션을 개발한다고 하면 뭐가 필요한지, 어디까지 구현해야 하는지에 대해서는 다소 막막했을 것이다.

그런 이유로 온전한 Microservice를 구축하기 위해 개발자로서 고려해야 할, 개발해야 될 주요 패턴들에 대해서 알아보고 패턴별 필요한 Spring Cloud 기술셋에 대해서 살펴보았다.

이를 바탕으로 Microservice 기반의 애플리케이션을 구축하는 초기 설계 시점에, 더 이상 고민하지 않고 해야 될 작업들을 신속히 정의할 수 있고 업무 분장까지 할 수 있을 것이다.

Ref