- 스프링 프레임워크에서 분산 시스템인 마이크로서비스 아키텍처(MSA)를 구축할 때 유용한 도구를 제공하는 프레임워크입니다.
- RAD(Rapid Application Development) 방법론을 채택하여 스프링 프레임워크와 같이 자바 기반으로 개발되며 클라우드 환경에서의 빠르고 안정적인 애플리케이션 개발을 위한 여러 기능을 제공합니다. - 주요 기능으로는 서비스 디스커버리, 로드밸런싱, 구성 관리, 회로 차단, 분산 추적 등이 있습니다.
- 서버의 성능을 향상하는 것으로 단일 서버에 더 많은 하드웨어 자원을 추가하는 것입니다.
💡 수평 확장(Scale-out)
- 서버의 용량을 늘리는 것으로 ‘서버 인스턴스’를 추가하여 부하를 분산시키는 것입니다.
2. Spring Boot vs Spring Cloud
💡 Spring Boot vs Spring Cloud?
- Spring Boot와 Spring Cloud는 모두 Spring Framework 기반으로 개발이 되었지만 각각의 목적과 기능의 차이가 있습니다. - Spring Boot는 ‘단일 애플리케이션 개발’을 위한 프레임워크이며, Spring Cloud는 ‘분산 시스템의 개발 및 운영’을 위한 프레임워크입니다. - Spring Cloud는 Spring Boot에서 제공하는 기능을 기반으로 분산 시스템에서 필요한 다양한 기능들을 추가로 제공합니다.
- 따라서 ‘Spring Cloud라는 환경하에 각각의 단일 애플리케이션은 Spring Boot를 이용하여 개발합니다.’
분류
Spring Boot
Spring Cloud
프레임워크 종류
단일 서비스 개발을 위한 프레임워크
분산 시스템 개발을 위한 프레임워크
장점
빠른 개발과 배포, 간단한 설정, Spring 기반으로 다양한 라이브러리 지원
분산 시스템 개발에 필요한 다양한 기능 제공, 클라우드 네이티브 애플리케이션 개발에 적합
단점
대규모 분산 시스템에서는 한계가 있음(서비스 간의 통신, 관리 등의 기능이 부족함)
설정이 복잡하고 러닝커브가 높음
주요 모듈
Spring MVC, Spring Data, Spring Security, Spring Boot Actuator
Spring Cloud, Config, Discovery, Routing, Circuit Brreaker, Messing
3. Netflix OSS(Neflix Open Source Software)
💡 Netflix OSS(Open Source Software) 란?
- Netflix에서 개발한 오픈소스 소프트웨어들의 집합으로 클라우드 네이티브 애플리케이션을 만들기 위한 다양한 도구들을 자체적으로 사용하면서 성능이 검증된 라이브러리로 제공을 합니다. 이를 통해서 클라우드 네이티브 애플리케이션 개발과 운영을 보다 쉽고 간편하게 만들어 줍니다. - 대표적인 도구로는 Eureka, Hystrix, Ribbon, Zuul 등이 있습니다.
1. 분산/버전 구성(Distributed/versioned configuration) : Spring Cloud Config
💡 분산/버전 구성(Distributed/versioned configuration)
- Spring Cloud는 분산 시스템에서 구성 데이터를 효과적으로 ‘관리’ 하기 위한 분산/버전 구성 기능을 제공합니다. 이를 통해 시스템 구성 요소의 동적인 변경과 관리가 가능해집니다.
- Spring Cloud에서는 분산/버전 구성을 위하여 ‘Spring Cloud Config’ 컴포넌트를 사용합니다. - 설정 파일은 Git 저장소, 파일 시스템, Vault 등을 이용하여서 관리할 수 있습니다.
💡 분산/버전 구성(Distributed/versioned configuration) 동작 비교
- Spring Boot 환경에서는 같은 단일 애플리케이션의 경우는 애플리케이션이 동작을 할 때 ‘설정 파일’을 읽어와서 수행합니다.
- Spring Cloud 환경에서는 MSA를 지원할 때에는 환경 자체의 값들을 자유롭게 변경, 처리할 수 있어야 합니다. 그렇기에 중앙 저장소(Spring Cloud Config Server)에서 ‘모든 설정값을 관리’하고 개별 서비스는 ‘중앙 저장소에 요청’을 하여서 가져오는 형태로 사용이 됩니다.
종류
설명
Spring Config Server
구성 정보를 저장하고 관리하는 중앙 집중식 서버를 의미합니다.
Spring Config Client
Config Server로 부터 구성정보를 가져와서 애플리케이션의 환경정보를 설정합니다
💡 설정 관리 방법 : 전반적인 과정
- 최초 애플리케이션(Web/Mobile/IoT)에서 구동 시 서비스로 요청이 되며 서비스는 Config Server로 요청하여서 Git Repository로부터 설정 정보를 요청 및 응답을 받아서 서비스의 설정 파일을 구성합니다.
- 분산 시스템에서 애플리케이션의 ‘설정 정보를 중앙 집중적으로 관리’할 수 있는 기능입니다. 이를 통해 애플리케이션의 설정 정보를 변경하더라도 애플리케이션을 재시작할 필요 없이 변경된 설정 정보를 즉시 반영할 수 있습니다.
- Spring Cloud에서는 분산 구성을 위해 ‘Cloud Config Server’를 사용합니다. 이를 통해 설정 정보를 중앙 집중적으로 관리하고, 다른 애플리케이션에서 설정 정보를 가져와 사용할 수 있습니다.
💡 설정 관리 방법 : ‘설정 파일’을 불러오기 과정
1. 클라이언트에서 최초 구동 시 서비스로 요청합니다.
2. 서비스는 ‘설정 정보’를 Config Server로 요청합니다.
3. Config Server는 Git Repository로 설정 정보를 찾아서 반환받습니다.
4. Config Server는 찾은 ‘설정 정보’를 서비스로 전달합니다.
💡 설정 관리 방법 : ‘설정 파일’ 변경 과정
1. 사용자는 Git Repository의 설정 파일을 갱신합니다.
2. Client는 변경 사항의 갱신을 위해서 서비스로 /actuator/refresh를 호출합니다.
3. 서비스는 변경 사항 갱신에 따른 설정값을 Config Server로 요청합니다
4. Config Server는 Git Repository를 통해서 설정값을 찾아서 반환받습니다.
5. Config Server는 최신 설정값을 Server로 갱신합니다.
2. 버전 구성(Versioned Configuration)
💡 버전 구성(Versioned Configuration)이란?
- 애플리케이션의 ‘설정 정보를 버전 관리할 수 있는 기능’입니다. 이를 통해 설정 정보의 변경 이력을 관리하고, 필요한 경우 이전 버전의 설정 정보로 되돌릴 수 있습니다.
- 버전 구성을 위해 Git 또는 Subversion과 같은 버전 관리 시스템을 사용합니다. 이를 통해 Git 또는 Subversion에 설정 정보를 저장하고, 버전 관리를 할 수 있습니다. - 또한 설정 정보는 Git 브랜치와 태그를 사용하여 서로 다른 구성 환경에 대한 구성 파일을 저장할 수 있습니다. - 예를 들어, "dev" 브랜치에는 개발 환경을 위한 구성 파일이 있고, "prd" 브랜치에는 운영 환경을 위한 구성 파일이 있습니다.
2. 서비스 등록 및 검색(Service registration and discovery) : Spring Cloud Discovery
💡 서비스 등록 및 검색(Service registration and discovery)
- 분산 시스템에서 서비스 간의 서비스를 ‘등록’하거나 ‘검색’을 효율적으로 처리하도록 기능을 제공합니다.
- 서비스의 등록은 중앙 저장소(Spring Cloud Config Server)에 등록하여서 이를 기반으로 하여서 검색이 수행됩니다. - 이 기능을 이용하면 다수의 서비스 인스턴스를 자동으로 등록하고 검색할 수 있어서, 서비스의 통신을 보다 쉽게 구현할 수 있습니다. 또한 해당 등록 시점은 서비스가 실행되면 자동으로 등록이 되며 Discovery Server에 등록정보 (인스턴스 ID, 서비스 위치 정보)가 전송됩니다
[ 더 알아보기 ] 💡 서비스 인스턴스란?
- 분산 시스템에서 실행 중인 서비스(애플리케이션)의 한 인스턴스를 의미합니다. 즉, 서비스 인스턴스는 서비스의 실행 가능한 하나의 단위입니다. - Spring Cloud의 서비스 등록 및 검색 기능을 이용하면 다수의 서비스 인스턴스를 자동으로 등록하고 검색할 수 있어서, 서비스 간의 통신을 보다 쉽게 구현할 수 있습니다.
1. 서비스 등록
💡 서비스 등록(Service registration)
- 서비스 등록을 위해서 Eureka와 Consul, Apache Zookeeper와 같은 다양한 서비스 디스커버리 클라이언트를 지원합니다.
- 이를 이용하면 서비스 인스턴스를 자동으로 등록할 수 있습니다. 등록된 서비스는 클라이언트에서 검색할 수 있으며 이를 통해 다른 서비스와의 통신을 수행할 수 있습니다.
3. 서비스 간 호출(Service-to-Service calls) : Spring Cloud Discovery, Spring Cloud Routing 컴포넌트
💡 서비스 간 호출(Service-to-Service calls)?
- 분산 시스템에서 서비스와 서비스 간의 호출은 빈번하게 발생합니다. 이를 위해 API Gateway를 통하여서 서비스를 호출할 수도 있지만 내부망에서 SSL, 필터링 처리 등 불필요한 부하가 발생합니다.
- 이를 위해 중앙 저장소(Spring Cloud Config Server)에 사전에 등록된 서비스에 대해서 서비스 간의 데이터를 전달하고 내부적으로 HTTP를 사용하여 통신합니다.- 서비스 간의 호출을 위해 RestTemplate, Feign, WebClient 기술을 사용하여 구성합니다.
4. 라우팅(Routing) : Spring Cloud Routing
💡 라우팅(Routing) 이란? - 특정 네트워크 내부에서 목적지를 찾아가는 과정을 의미합니다.
- 대표적으로 Spring Cloud Routing에서는 Cloud Load Balancer와 Gateway, OpenFeign가 있습니다.
💡 API 게이트웨이(API Gateway)란?
- ‘클라이언트에서 API로 보내는 요청’을 각각의 서비스에 맞게 라우팅 해주는 역할을 수행합니다.
- API Gateway를 사용함으로써 외부에 노출되는 포인트를 하나로 만들어서 관리가 편리해지며 인증 혹은 SSL 처리를 담당하여서 게이트웨이 내부 모듈을 더 간단하게 만들도록 도와줍니다.
- 클라이언트 측에서 사용하는 모바일 앱 또는 웹 애플리케이션과 같은 프론트엔드에서 백엔드 서비스에 직접 접근하는 것보다 API Gateway와 같은 ‘중간 레이어’를 통해 백엔드 서비스를 호출하는 것을 의미합니다.
- 이를 사용하면 클라이언트 유형에 대해 별도의 API를 노출하므로 클라이언트 유형에 따라 서로 다른 백엔드 서비스를 호출할 수 있습니다. 이에 따라 클라이언트의 요구 사항에 맞게 서비스를 제공할 수 있습니다.
4.1. Zuul을 이용하기 : API Gateway
💡 Spring Cloud Zuul 이란? - Netflix에서 개발한 오픈소스 프로젝트로 클라이언트와 마이크로서비스 간의 인증, 라우팅, 부하 분산 등의 기능을 제공합니다.
- 서비스 디스커버리와 연계하여 동작하며 Eureka, Consul, Zookeeper 등의 서비스 디스커버리 서버를 지원합니다. 또한 다양한 필터들을 제공하여 Request/Response에 대한 로그 및 성능 측정, 인증/인가, 헤더 조작 등의 작업을 수행할 수 있습니다.- 이를 통해 클라이언트 요청을 안전하게 처리하고, 로드밸런싱 및 트래픽 라우팅 등의 기능을 수행할 수 있습니다.
💡 API Gateway: Zuul을 이용한 아키텍처
1. 클라이언트(사용자)는 API Gateway(Zuul)로 API 요청을 합니다.
2. API Gateway는 Discovery Server(Eureka Server)로 백엔드 서비스에 대한 위치에 대한 Query(조회)를 수행하여 값을 받습니다.
- Netflix에서 개발한 오픈소스 프로젝트로 클라이언트 측 ‘적재 분산 기술’을 제공하는 라이브러리입니다.
- 주요한 기능으로는 로드밸런싱, 장애 조치, 지연 시간 및 재시도와 같은 기능을 제공합니다.
- Ribbon은 Eureka와 같은 서비스 디스커버리 클라이언트와 함께 사용할 수 있으며, 클라이언트 측 부하 분산을 수행합니다. 이는 클라이언트 측 로드밸런싱을 통해 서버의 작업 부하를 분산시키므로 서버 측에 대한 부하 분산을 위해 로드밸런서를 구성하거나 관리할 필요가 없습니다.
💡 Client Side LoadBalancer: Ribbon을 이용한 아키텍처
1. 서버를 기준으로 Discovery Server로 서비스 간의 호출을 위한 서비스 인스턴스를 요청합니다. : Service Discovery
2. Discovery Server는 Load Balancer(Ribbion)로 서비스 인스턴스를 요청합니다. : Request Service Instance
3. Load Balancer(Ribbion)는 서비스 인스턴스를 확인하여 서비스로 응답을 해줍니다. : Response Service Instance
4. 서비스에서는 응답받은 인스턴스를 통해서 다른 서비스와 서로 호출합니다. : Service-to-Service calls
6. 서킷 브레이커(Circuit Breakers) : Spring Cloud Circuit Breaker
💡 서킷 브레이커(Circuit Breakers) 란? - 분산 시스템에서 장애 발생 시 ‘전체 시스템의 장애를 방지’ 하기 위해 사용되는 기술을 의미합니다. 참고로 서킷 브레이커는 일종의 전기 회로의 개념과 비슷합니다.
- 주요한 기능으로는 장애 회복 기능, 서킷 브레이커 패턴 구현, 요청 실패 처리, 장애 상황 모니터링 및 알림 기능을 제공합니다.
💡 서킷 브레이커의 동작
- 분산 시스템에서는 다양한 서비스들이 서로 연동되어 동작합니다. 그렇기에 하나의 서비스의 장애가 다른 서비스까지 전파될 가능성이 있고 모든 서비스가 동작하지 않는다면 전체 시스템이 마비될 수 있는 상황이 될 수 있습니다. 이를 방지하기 위해 장애가 발생한 서비스에 대한 요청을 빠르게 차단하며 이후 복구되기 전까지 다른 서비스에 영향을 주지 않습니다.
7. 글로벌 락 (Global locks) & 지도자 선출, 클러스터 상태 (Leadership election and cluster state) : Spring Cloud Config
💡 글로벌 락 (Global locks) & 지도자 선출, 클러스터 상태 (Leadership election and cluster state)는 분산 시스템의 일관성, 가용성 및 분할 허용성을 보장하는 데 중요한 기능입니다.
💡 글로벌 락(Global Locks) 이란?
- 분산 시스템에서 ‘여러 서버에서 동시에 접근’할 수 있는 데이터에 대한 ‘접근을 제한’ 하기 위한 메커니즘입니다. - 예를 들어, 동시에 여러 클라이언트가 동일한 데이터를 요청하면, Global Locks는 이를 순차적으로 처리하도록 강제합니다. - 이를 통해 데이터의 일관성을 유지할 수 있습니다.
💡 지도자 선출(Leadership Election) 이란?
- 분산 시스템에서 여러 서버 중에서 ‘하나의 서버가 리더 역할’을 맡아 해당 서비스를 제공하도록 하는 기능입니다 - 이를 통해 분산 시스템에서 데이터 일관성을 유지하고, 서버의 부하를 분산시킬 수 있습니다.
💡 클러스터 상태(cluster state)란? - 분산 시스템에서 ‘서버들의 상태와 위치를 파악하고 이를 관리’하는 기능입니다. - 이를 통해 서버의 추가, 삭제, 장애 대응 등을 보다 효과적으로 처리할 수 있습니다.
- 해당 기능들은 Spring Cloud Config의 ‘Spring Cloud Consul’을 통해서 기능을 구현할 수 있습니다.
7.1. Spring Cloud Consul
💡 Spring Cloud Consul 란? - Spring Cloud에서 지원하는 서비스 디스커버리와 구성 관리 기능 및 기타 기능을 제공하는 서비스 메시입니다.
- Consul을 통해서 분산 시스템에서 서비스 검색, 설정 및 분배, Health Check 및 글로벌 Lock, 강력한 쿼리 기능과 키/값 저장소 등을 제공하여 분산 시스템에서 발생하는 여러 문제를 해결할 수 있습니다.
- Spring Cloud Consul 라이브러리를 사용하여 Spring 애플리케이션에서 Consul에 등록된 서비스를 가져와서 사용하고 Consul의 다양한 기능을 활용하여 분산 시스템 기능을 구현합니다.
관계
설명
서비스 디스커버리
서비스 인스턴스의 등록, 발견 및 감시를 수행합니다. Consul 서버와 통신하여 서비스 디스커버리를 구현합니다.
구성 관리
Key/Value 저장소에 저장됩니다. Consul 서버와 통신하여 구성 데이터를 가져오고 업데이트 합니다.
기타 기능
Consul 클러스터와의 상호 작용을 위한 API를 제공하며, Consul의 이벤트 시스템을 사용하여 이벤트를 수신하고 처리할 수 있습니다.
[ 더 알아보기 ] 💡 서비스 메시(Service Mesh) 란? - 분산 시스템에서 서비스 간 통신을 관리하는 패턴입니다. 이 패턴은 서비스 간 직접 통신 대신에 간접적인 통신을 통해 통신을 관리합니다.
- 이를 위해 메시 서비스가 서비스 간의 통신을 위한 라우팅, 부하 분산, 서비스 디스커버리 등을 제공합니다.- 서비스 메시를 적용하면 개발자는 서비스 간의 결합도를 낮출 수 있고, 확장성과 유연성을 높일 수 있습니다. 또한, 서비스 간 통신의 안정성과 가용성을 보장할 수 있습니다.
8. 분산 메시징 (Distributed messaging) : Spring Cloud Messaging
💡 분산 메시징(Distributed messaging) 이란?
- ‘여러 서비스 간의 통신’을 위해 사용되는 시스템입니다. 이는 여러 서버에 걸쳐 있는 애플리케이션들이 서로 데이터나 메시지를 주고받을 수 있도록 해줍니다.
- 주요한 기능으로는 메시지 브로커와의 통합, 메시지 라우팅, 메시지 필터링, 메시지 변환 등의 기능이 있고 이를 처리하기 위해 Spring Cloud에서는 메시징 솔루션으로 Apache Kafka, RabbitMQ, Amazon Kinesis 등이 있습니다.
8.1 분산 메시징의 예시
💡 분산 메시징의 예시
- 배달 서비스를 개발할 때에 배달 서비스에서는 ‘주문이 완료된 상태’라고 가정을 합니다. - 그렇다면 ‘고객’에게 주문 완료 메시지를 보내야 하고 ‘상점’에도 주문 완료 메시지를 보내야 하며, 또한 ‘서비스 메인 모듈’에도 메시지를 보내야 합니다. - 이렇게 하나의 ‘주문이 완료된 상태’에 대해서 다양한 곳으로 메시지를 전송해야 하는 상태면 분산 메시징이 사용이 됩니다.
8.2. RabbitMQ를 통한 분산 메시징 과정
💡 [분산 메시징 과정]
1. 생산자(Producer)가 메시지를 발행합니다.
2. 생산자(Producer)는 생성한 메시지를 브로커의 Exchange로 메시지를 전달합니다.
- Exchange는 메시지를 받아 라우팅(Routing)을 수행합니다 - 라우팅 키(Routing Key)를 이용하여 메시지를 어떤 큐로 전달할지 결정합니다. - 라우팅을 위해 Exchange Type을 제공합니다 - Exchange Type을 이용하여 메시지를 적절한 큐에 전달합니다.
3. Exchanges는 바인딩(Binding)을 통해서 큐(Queue)로 전달합니다.
4. 소비자(Consumer)는 자신이 바라보고 있는 큐를 구독(Subscribe)하다가 큐가 삽입이 되었을 때 메시지를 수신하여 처리합니다.
용어
분류
메시지
송신자와 수신자간에 전송이 되는 데이터 덩어리를 의미합니다.
메시지 브로커(Message Broker)
메시지를 생성하고 소비하는 클라이언트 간에 메시지를 전달하는 미들웨어입니다. ex) Apache Kafka, RabbitMQ, Amazon Kinesis
Exchange
메시지를 수신하고 처리할 대상을 결정하는 구성요소를 의미합니다. 주로 메시지를 수신하고 특정 큐로 보내는 역할을 수행합니다.
생산자(Producer)
메시지를 생성하고 메시지 브로커에 ‘전송’하는 구성요소를 의미합니다.
소비자(Consumer)
메시지 브로커에서 메시지를 가져와서 ‘수신’하고 ‘처리’를 하는 주체를 의미합니다.
바인딩(Binding)
클라이언트 애플리케이션과 메시징 시스템 간의 연결을 하는 과정을 의미합니다.
메시지 큐(Message Queue)
메시징 시스템에 저장된 메시지를 의미하며 송신자가 메시지를 전송하면 이를 수신자가 처리할때까지 대기시킵니다
8.2. 분산 메시징의 주요한 기능
기능
설명
메시지 브로커와의 통합
메시지 브로커와의 연결 설정 및 통신 기능을 제공합니다
메시지 라우팅
메시지의 수신 및 전달 경로 설정 기능을 제공합니다
메시지 필터링
특정 메시지를 수신하거나 무시하는 필터링 기능을 제공합니다
메시지 변환
메시지의 형식 변환 기능을 제공합니다
8.3. 분산 메시징을 지원하는 라이브러리와 프레임워크
라이브러리/ 프레임워크
설명
Spring Cloud Stream
메시지를 생성하고 전송하고 수신하는데 사용할 수 있는 프레임워크입니다.
Spring Cloud Bus
분산 시스템에서 구성 요소들 간의 메시지 전송을 지원하는 라이브러리 입니다.
Spring Cloud Stream Binder
- Spring Cloud Stream에서 다양한 메시징 미들웨어를 연결하는 데 사용할 수 있는 라이브러리입니다. - Kafka를 사용하는 경우 Spring Cloud Stream Kafka Binder를 사용하여 애플리케이션과 Kafka를 연결할 수 있습니다.