베스핀글로벌 / 윤영기 이사


?

1. Microservice Architecture

Microservice Architecture란 단일 애플리케이션을 작은 단위의 서비스들로 독립적으로 분리하여 서로 네트워크 통신을 하도록 구성하는 애플리케이션 개발 방법으로서, 개발과 배포의 속도를 높임으로써 비즈니스 혁신을 가속화 할 수 있다는 점 때문에 최근 각광받고 있다.

?


<그림1. MSA 도입 목적>


?




?

2. Microservice Architecture 구성

Microservice Architecture는 Microservice 구현을 위한 Application Architecture와 Microservice를 실행하고 운영하기 위한 Infrastructure Architecture로 구분할 수 있다.

Microservice Application Architecture는 프로그램 내부의 아키텍처라는 의미를 담아 Inner Architecture라고 부르기도 하며, Microservice Infrastructure Architecture는 프로그램 외부의 아키텍처라는 의미를 담아 Outer Architecture라 부르기도 한다.

(본 문서에서도 편의상 Inner Architecture, Outer Architecture라 부르기로 한다.)

?

2-1. Inner Architecture

Inner Architecture는 Microservice개발을 위해 서비스를 분할 및 식별하고, 식별된 마이크로서비스간 통신 및 데이터를 처리하는 방식들을 의미한다.

아래는 Inner Architecture의 구성요소들에 대해서 간략하게 정리하였으며, 상세한 설계원칙이나 가이드는 본 문서의 취지와 맞지 않으므로 다루지 않겠다.

  • 서비스 분해 및 식별
    새롭게 개발하려는 서비스나 기존 모놀리식(Monolith)으로 개발되어진 서비스를 여러 개의 작은 서비스(마이크로서비스)들로 나누는 것
  • 마이크로서비스간 통신
    마이크로서비스는 서로 독립적인 네트워크주소를 갖기 때문에, 모놀리식(Monolith) 애플리케이션에서 다른 클래스나 패키지를 호출하는 방식과는 다르게 네트워크 통신 프로토콜을 통해 서로 통신을 하여야 하며, 많이 사용되는 통신 방식은 REST API, RPC, gRPC, Message 가 있다.
  • 데이터베이스 구조
    마이크로서비스는 독립적으로 개발되어야 하며, 다른 마이크로서비스와 느슨한 결합상태를 유지해야 하므로 독립적인 데이터베이스를 소유하는 것이 바람직하며, 경우에 따라서는 일부를 공유하기도 한다.
  • 분산 트랜잭션 처리
    클라이언트의 요청(특히 데이터의 변경 요청)이 하나의 마이크로서비스에서 끝나지 않고, 두 개 이상의 마이크로서비스를 거치는 과정에서 데이터의 일관성과 정합성을 유지할 수 있도록 처리하여야 하며, 실패에 대한 보상처리가 필요하다.
  • 애플리케이션 프레임워크
    마이크로서비스를 효율적으로 개발하기 위해서는 개발 목적, 기술수준, 사용하려는 기술의 지원범위 등을 고려하여 프레임워크를 선택하는 것이 필요하다.
    마이크로서비스가 등장하던 초장기부터 최근까지는 Netflix가 개발한 Netflix OSS 그리고 그 기술들을 채용한 Spring Cloud가 주류였으며, 확장성성능?효율성 등으로 점차 다양한 프레임워크를 사용하려는 기조를 보이고 있다.

2-2. Outer Architecture

Outer Architecture는 Microservice를 실행하고 안정적으로 동작하도록 모니터링과 운영관리 등을 하기 위해 필요한 SW들을 적절히 구성하는 것을 의미한다.
아래는 Outer Architecture의 구성요소이다.

?

  • API Gateway
    API Gateway는 API서버 즉 마이크로서비스 앞 단에서 모든 마이크로서비스들의 엔드포인트를 단일화 해주는 기능을 하며, API에 대한 인증 및 인가, 라우팅 등 기본 기능부터 보안, 프로토콜 변환, 통제, 통계 및 과금까지의 고급기능을 제공한다.
  • Service Mesh
    Service Mesh는 마이크로서비스들 간의 네트워킹을 제어하고 시스템의 가용성을 유지해주는 역할을 하며, 서비스 발견, 트래픽 관리, 라우팅 등 기능을 제공한다.
    API Gateway가 클라이언트와 마이크로서비스 사이를 통제한다고 보면, Service Mesh는 마이크로서비스와 마이크로서비스 사이를 통제하는 역할로 볼 수 있다.
  • Runtime Platform
    Runtime Platform은 마이크로서비스를 실행하기 위한 실행환경을 제공하고, 그 실행환경을 관리하는 역할을 한다.
    초창기에는 가상서버(VM)을 이용하는 경우도 있었으나, 최근에는 컨테이너 기술 또는 서버리스 기술이 주류를 이룬다.
  • Monitoring
    분산된 환경에서 마이크로서비스들의 상태를 일일이 모니터링하고 이슈에 대응할 수 있는 헬스체크 및 모니터링 역할을 한다.
    일반적인 APM부터 컨테이너 리소스나 로그모니터링 툴이 필요하며, 특히 여러 마이크로서비스를 거치는 트래픽의 흐름을 추적하고 모니터링 할 수 있는 트레이싱 도구가 반드시 필요하다.
  • CI/CD
    마이크로서비스의 지속적인 통합 및 배포를 위한 DevOps 도구
  • Backing Service
    마이크로서비스 실행을 위해 네트워크를 통해서 사용할 수 있는 모든 서비스들을 의미하며, 데이터베이스, 스토리지, 메시징 시스템 등이 이에 속한다.

?




?

3. Microservice Architecture의 세대 변화

지금까지 Microservice Architecture의 구성요소들을 간략하게 살펴보았다. Microservice 관련 기술은 빠르지는 않지만 분명한 변화를 하고 있으며, 그 중에서 아키텍처에 큰 영향을 미치는 기술의 변화를 세대 변화를 다음과 같이 정의할 수 있다.


<그림2. MSA 기술 트렌드 (출처: 베스핀글로벌)>




  • Microservice Architecture 1세대 : Spring Cloud/Spring Boot 기반의 Java Application Architecture
  • Microservice Architecture 2세대 : Spring Cloud/Spring Boot/Vert.X+ Kubernetes 기반의 Polyglot Architecture
  • Microservice Architecture 3세대 : SideCar방식의 Service Mesh + Kubernetes 기반의 Polyglot Architecture
  • Microservice Architecture 4세대 : SideCar방식의 Service Mesh + Kubernetes + Serverless 기반의 Polyglot Architecture

?

3-1. Microservice Architecture 1세대

Netflix는 자신들의 Microservice를 효율적으로 운영관리하기 위해 Ribbon, Eureka, Hystrix 등의 클라우드 인프라 라이브러리를 개발하였으며, 2015년에 Spring진영에서는 이 라이브러리들을 적용하여 Spring Cloud를 내놓았다.

Java 애플리케이션을 보다 신속하게 개발할 수 있는 Spring boot과 함께 Spring Cloud는 마이크로서비스를 효율적이고 안정적으로 개발 및 운영할 수 있는 프레임워크로 알려지면서 많은 개발자들이 Spring Cloud와 Spring Boot을 이용하여 마이크로서비스를 개발하였다.

?
Zuul마이크로서비스 아키텍처에서 여러 클라이언트 요청을 적절한 서비스로 프록시하거나 라우팅하기 위한 Gateway서비스
Spring Cloud Config? 중앙집중식 Config서비스로 어플리케이션 설정에 필요한 파일을 마이크로서비스와 분리 저장하는 역할을 담당한다.

? 각 마이크로서비스 설정을 git 또는 Config파일로 저장 및 관리한다.
Eureka? 서비스 디스커버리를 제공하는 오픈소스로, 서버와 클라이언트로 이루어져있다.
? 마이크로서비스가 기동시 자신의 정보를 Eureka서버 에 등록하고, 등록된정보를 다른 클라이언트에 게 전달하여 서로 통신이 가능하도록 함
Hystrix마이크로서비스의 회복성 패턴을 위한 Circuit breaker
Ribbon클라이언트가 서비스 호출에 대한 분산처리가 되도록 한다.
Spring cloud StreamRabbitMQ, Apache Kafka 등과 같은 메시지 브로커와 연결할 수 있는 공통 기능을 제공한다.

<표1. Spring Cloud의 구성요소>


?

하지만, 마이크로서비스를 개발하는데 있어 Spring Cloud/Spring Boot이 장점만 있는 것은 아니다. Spring Framework가 java 애플리케이션에 특화되어 있는 만큼 python이나 node.js, go 등 다양한 프로그램 랭귀지로 마이크로서비스를 개발하기에는 많은 한계가 있다. 또한 Zuul, Eureka, Hystrix 등을 사용하기 위해서 프로그램 소스코드로 일부를 설정 및 구현해야 하므로, 인프라 레이어와 애플리케이션간의 종속성이 높아진다는 단점이 있다.

아래 그림은 Spring Cloud의 Hystrix를 사용하기 위해서 Application 소스코드로 Fallback Class를 구현하는 예시이다. HystixCommand를 상속받아서 구현하고 있는 것을 알 수 있다.


<그림3. Hystrix fallback 클래스 작성 예 (출처: https://github.com/Netflix/Hystrix/wiki/How-To-Use)>


?

3-2. Microservice Architecture 2세대

Microservice Architecture 2세대의 가장 큰 특징은 Container와 Kubernetes이다. 클라우드 인프라의 리소스를 보다 효율적으로 운용할 수 있으며 애플리케이션 기동시간이 기존의 가상서버(VM)보다 월등이 빠르고, 또한 이식성이 매우 높다는 이유로 활용률이 증가하면서, 마이크로서비스의 실행환경으로 Container와 Kubernetes가 사실상 표준이 되었다.

Kubernetes를 도입한다는 것은 단순히 마이크로서비스가 배포된 컨테이너를 오케스트레이션 하는 것에 그치지 않는다. 그 이유는 Spring Cloud의 Eureka, Ribbon, Config와 비슷한 기능들을 Kubernetes에서도 제공하고 있기 때문이다.

?
Spring CloudKubernetes
Spring Cloud ConfigConfigmap or SecretPOD의 설정정보나 환경변수를 관리하기 위한 저장소
EurekaKubernetes MasterPOD의 전체 라이프사이클을 관리
RibbonServicePOD 집합에 대한 단일 DNS명 및 고유 로컬 서비스IP를 부여하는 리소스로 POD간 로드밸싱을 수행

<표2. Spring Cloud와 Kubernetes 비교>


?

?


<그림4. Kubernetes & Spring Cloud Architecture 예>


?

Spring Cloud의 Eureka와 Config는 Server ? Client 구조이기 때문에 별도의 가상서버나 POD로 Server를 올린 후 개발자나 운영자가 운영관리 해야 하지만, Kubernetes는 이미 구축된 상태에서 안정적으로 기능을 이용할 수 있기 때문에 개발자에게는 선택의 폭이 조금 다양해졌다고 볼 수 있다.

실제로 필자는 Spring Cloud사용이 어려웠던 프로젝트에서 표 2와 같은 Kubernetes 컴포넌트를 이용하여 MSA아키텍처를 구현한 경험이 있다.

또 다른 특징은 애플리케이션 프레임워크의 선택이 다양해졌다는 것이다. 그 대표적인 프레임워크로는 Vert.x가 있다.

Vert.x는 이벤트드리븐방식의 애플리케이션 프레임워크이며, java외 node.js, python 등 다양한 프로그램 랭귀지를 사용할 수 있는 Polyglot 프레임워크이며, 싱글쓰레드 기반으로 이벤트 루프를 통해 워크로드를 다중화 한다.

?


<그림5. Vert.x의 Event-loof thread (출처: https://vertx.io/introduction-to-vertx-and-reactive)>


?

또한 Spring Cloud의 Hystrix와 같은 Circuit Breaker을 포함한다.


<그림6. Ver.x Circuit Breaker 구현 예 (출처: https://vertx.io/docs/vertx-circuit-breaker/java)>


?

하지만, 여전히 인프라 레이어와 애플리케이션간의 종속성부분은 극복하지 못하였다.

?

3.3 Microservice Architecture 3세대

Microservice Architecture 3세대로 넘어오면서 가장 큰 변화는 인프라 레이어와 애플리케이션의 완전한 분리이다.

애플리케이션과 독립적으로 동작하면서 애플리케이션의 네트워크 통신과 라이프사이클을 효과적으로 관리하기 위한 Sidecar방식의 SW를 도입하면서부터 개발자는 더 이상 Hystrix, Ribbon, Eureka등을 사용하기 위해 소스코드를 작성하는 수고를 덜게 되었다.

Sidecar란 모터사이클이나 자전거 등의 이륜차에 옆에 장착하는 보조차량의 개념을 채용한 단어이며, Kubernetes의 POD안에 컨테이너와 독립적으로 동작하는 별도의 컨테이너를 의미한다.

?
이륜차의 SidecarKubernetes의 Sidecar

<그림7. Sidecar>


?

사이드카 서비스는 애플리케이션의 일부일 필요는 없지만 애플리케이션에 연결되어 있습니다. 상위 애플리케이션의 이동 위치로 어디든 이동합니다. 사이드카는 기본 애플리케이션을 사용하여 배포되는 프로세스 또는 서비스를 지원합니다. 오토바이의 경우 사이드카는 하나의 오토바이에 연결되고 오토바이는 자체 사이드카를 가질 있습니다. 마찬가지로 사이드카 서비스는 해당 상위 애플리케이션과 함께 운용됩니다. 애플리케이션의 인스턴스에 대해 사이드카의 인스턴스가 배포되고 옆에 호스트 됩니다.

사이드카 패턴 사용의 장점은 다음과 같습니다.

  • 사이드카는 런타임 환경 프로그래밍 언어와 관련하여 해당 기본 애플리케이션과 독립적이므로 언어마다 하나의 사이드카를 개발할 필요가 없습니다.
  • 사이드카는 기본 애플리케이션과 동일한 리소스에 액세스할 있습니다. 예를 들어 사이드카는 사이드카 기본 애플리케이션 다에서 사용하는 시스템 리소스를 모니터링할 있습니다.
  • 기본 애플리케이션에 대한 사이드카의 근접도로 인해 간의 통신 대기 시간이 길지 않습니다.
  • 확장성 메커니즘을 제공 하지 않는 응용 프로그램의 경우에도 사이드카를 사용 기본 응용 프로그램과 동일한 호스트 또는 하위 컨테이너에서 자체 프로세스로 연결 기능을 확장할 있습니다.

사이드카 패턴은 컨테이너와 함께 사용되는 경우가 많으며 사이드카 컨테이너 또는 사이드킥 컨테이너라고도 합니다.

<Azure Architecture Pattern: Sidecar Pattern 발췌>


?

Sidecar방식의 도입으로 Microservice개발에 좀더 다양한 프로그램 언어와 프레임워크를 사용할 수 있는 가능성이 열리게 되었다. 진정한 Polyglot을 할 수 있게 된 것이다.

Sidecar방식을 지원하는 Service Mesh는 Istio, Linkerd, Consul 등이 있다.

?

3.4 Microservice Architecture 4세대

Microservice Architecture 4세대의 특징은 컨테이너에서 서버리스로의 확장이다. 보다 빠르게 애플리케이션을 개발하고 배포하며 빅데이터, AI, 머신러닝 등 신기술을 더 빠르게 활용하기 위해서 서버리스의 수요가 점차 늘어나고 있다.

또한 서버리스를 지원하는 SW도 다양해지고 있다. 아래 몇 가지를 살펴보도록 하겠다.

  • 케이네이티브 (Knative)
    퍼블릭 클라우드 사업자(CSP)에서 제공하는 서버리스 서비스는 AWS Lambda, Azure Functions, Google Functions 등이 있다. 하지만 케이네이티브는 퍼블릭 클라우드에서 특정 CSP에 종속되지 않고 사용할 수 있으며, 프라이빗 클라우드에서도 사용 가능하다. 케이네이티브는 Google에서 Kubernetes에서 서버리스 애플리케이션을 실행하기 위해 개발한 오픈소스 소프트웨어이다.케이네이티브는 3가지 주요 컴포넌트(Build, Serving, Event)로 구성되어있다.
    - Build : 소스코드를 컨테이너이미지화 하고 Image Registry로 Push하는 역할
    - Service : 컨테이너에 이미지를 배포하고, 도메인을 구성하며 트래픽에 따라 Scale In/Out을
    관리하는 역할
    - Event : API, Kafka, Rabbit MQ, Web socket 등으로부터 들어오는 이벤트를 수신하여 서비스
    로 전달하는 역할, 특히 다양한 이벤트 소스를 통해 서비스를 실행 할 수 있다는
    것이 특징이다.
  • Serverless Framework
    Serverless Framework는 FaaS(Function as a Service)에 애플리케이션을 빠르게 구성하고 배포하기 위해 개발된 오픈소스 프레임워크이며, AWS Lambda, AWS S3, Azure Functions, Google Big Query, Twilio, Stripe, Algolia, Cloudflare, Knative 등 다양한 인프라 환경에 배포할 수 있다.
    또한, 로컬 시스템에서 AWS Lambda 및 API 게이트웨이를 에뮬레이트 하거나, CloudWatch 경보를 쉽게 추가할 수 있는 서버리스 플러그인 등 1000여개의 커뮤니티 플러그인을 제공한다.
  • Quarkus
    Quarkus는 Kubernetes 기본 JAVA프레임워크로서, 컨테이너용으로 JAVA를 최적화할 뿐 아니라 서버리스를 위한 효과적인 프레임워크이다.
    Quarkus Funqy는 AWS Lambda, Azure Functions, Knative 및 Knative Events(Cloud Events)와 같은 다양한 FaaS(Function as a Service) 환경에 배포할 수 있는 기능을 작성하기 위해 Java API를 제공한다.


<그림8. Funqy Basic>


?




?
저작권정책

K-ICT 클라우드혁신센터의 저작물인 『MSA(Microservice Architecture) 기술 트렌드』는 K-ICT 클라우드혁신센터에서 베스핀클로벌 윤영기 이사에게 집필 자문을 받아 발행한 전문정보 브리프로, K-ICT 클라우드혁신센터의 저작권정책에 따라 이용할 수 있습니다.
다만 사진, 이미지, 인용자료 등 제3자에게 저작권이 있는 경우 원저작권자가 정한 바에 따릅니다.