Notice
Recent Posts
Recent Comments
Link
«   2026/08   »
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31
Tags
more
Archives
Today
Total
관리 메뉴

나의 개발 일상 기록

[MSA] Spring Cloud Netflix 본문

MSA

[MSA] Spring Cloud Netflix

느린 거북이 2021. 7. 14. 00:22

Spring Cloud Netflix

넷플릭스 OSS와 Spring Cloud 관계

 

먼저 클라우드 환경에 특화된 프레임워크인 Spring Cloud를 살펴볼 필요가 있습니다. Spring Cloud는 Spring boot를 기반으로 MSA 구축에 특화된 라이브러리들의 집합입니다. Spring Cloud에는 Eureka, Hystrix, Ribbon, Zuul 등 많은 넷플릭스 OSS가 통합되어 있습니다. 이번 포스팅에서 알아볼 내용은 오픈소스 중에서도 Spring Cloud에 속해있는 Spring Cloud Netflix입니다.

 

1. Hystrix

Hystrix 구조

MSA도 특정 서비스에 과부하가 걸리거나 어떤 문제로 인해 정상적으로 작동하지 않으면 전체 서비스에 장애를 전파하는 경우가 있습니다. 특정 서비스에 문제가 생기더라도 전체적으로 장애가 확산하지 않도록 차단해주는 기능을 서킷 브레이커라고 하며 넷플릭스는 이를 Hystrix라는 이름으로 개발하였습니다.

 

기능적 관점에서 본 Hystrix의 주요 4가지 기능은 Circuit Breaker, Fallback, Thread Isolation, Timeout이 있습니다.

 

  • Hystrix 적용하기 예시

Hystrix Annotation사용

- Hystrix Javanica, Spring Cloud Netflix에 포함되어 있습니다.

@HystrixCommand
public String anyMethodWithExternalDependency(){
	// REST API로 다른 서버 호출
}

HystrixCommand 상속

public class SampleCommand extends HystrixCommand<String> {
	@Override
	protected String run(){
		// REST API로 다른 서버 호출
	}
}

 

Hystrix Command를 호출할 때 벌어지는 일

  • 이 메소드를 Intercept하여 대신 실행합니다. (Thread Isolation)
  • 메소드의 실행 결과 혹은 실패(Exception) 발생 여부를 기록하고 통계를 냅니다. 통계에 따라 Circuit Open 여부를 결정합니다. (Circuit Breaker, 통계는 인스턴스 단위로 내고 있고 인스턴스 안에서도 서킷 브레이크 단위로 통계를 냅니다.)
  • 실패한 경우 사용자가 제공한 메소드를 대신 실행합니다. (Fallback)
  • 특정 시간 동안 메소드가 종료되지 않은 경우 Exception을 발생시킵니다. (Timeout)

2. Hystrix - Circuit Breaker

 

Circuit Breaker는 API 호출 통계를 기반으로 상대 서비스에서 이상을 감지하면 즉시 통신을 중단합니다. 그러면 문제가 있던 서비스를 격리(Isolation)하게 되는데 이후에는 문제가 해결될 때까지별도의 스레드에서 밀린 작업을 수행하거나 호출 수를 제한합니다. 상태가 정상으로 돌아오면 통신을 연결하여 다시 호출을 받도록 합니다.

 

Circuit Breaker의 동작

  • 일정 시간 동안 일정 개수 이상의 호출이 발생한 경우, 일정 비율 이상의 에러가 발생하면 Circuit Open(호출 차단)을 하게 됩니다.
  • 일정 시간 경과 후에 단 한개의 요청에 대해서 호출을 허용하며(Half Open) 이 호출이 성공하면 Circuit Close(호출허용)하게 됩니다.
  • 예를들어, 10초간 20개 이상의 호출이 발생 한 경우, 50% 이상의 에러가 발생하면 5초간 Circuit Open하게 됩니다.

 

Circuit Breaker의 단위

  • Hystrix Circuit Breaker는 한 프로세스 내에서 주어진 CommandKey 단위로 통계를 내고 동작합니다. 즉, Circuit Breaker는 CommandKey 단위로 생성됩니다.
@HystrixCommad(commandKey = "ExtDep1")
public String anyMethodWithExternalDependency1(){
	// 서버 호출 #1
}
@HystrixCommad(commandKey = "ExtDep2")
public String anyMethodWithExternalDependency2(){
	// 서버 호출 #2
}

 

3. Hystrix - Fallback

 

Fallback은 정해진 시간 내에 호출이 실패하면 대신 동작하는 예외처리로 보면 됩나다. 개발자가 폴백 메소드를 구현함으로써 시스템 장애로부터 유연하게 복구를 실행할 수 있습니다. 또한, 서킷 브레이커의 정보나 각 서버의 상태를 확인할 수 있는 모니터링 서비스까지 제공하여 로그를 중앙 집중형으로 관리하고 검색할 수 있습니다.

 

Fallback으로 지정된 메소드는 다음의 경우에 메소드 대신 실행합니다.

  • Circuit Open
  • Any Exception(HystrixBadRequestException 제외)
  • Semaphore / ThreadPool Rejection
  • Timeout

Fallback 사용예시

@HystrixCommad(commandkey = "ExtDep1",
               fallbackMethod = "recommendFallback")
public String anyMethodWithExternalDependency1(){
	// 추천 서버 호출
}
public String recommendFallback(){
	return "<미리 준비된 상품 목록>";
}

 

HystrixBadRequestException 

  • 사용자의 코드에서 HystrixBadRequestException을 발생시키면 이 오류는 Fallback을 실행하지 않으며, Circuit Open을 위한 통계에도 집계되지 않습니다.  

Method Caller의 실수(ex 잘못된 파라매터의 전달)의 경우

  • HystrixBadRequestException을 Throw하게 작성이 필요합니다.

Caller의 실수를 다른 Exception으로 던진다면..

  • Circuit Breaker의 통계에 집계되어 Caller의 잘못으로 Circuit이 Open 됩니다.
  • Fallback이 실행되어 개발과정에 오류를 인지하지 못할 수도 있습니다.

4. Hystrix - Timeout

 

Hystrix에서는 Circuit Breaker단위로 (CommandKey 단위로) Timeout을 설정할 수 있다.

hystrix.command.<commandKey>.execution.isolation.thread.timeoutUnMilliseconds => Default 1초

 

5. Hystrix - Isolation

 

두가지 Isolation 방식을 Circuit Breaker별로 지정 가능합니다.

  • Semaphore
  • Thread (default)

Hystrix - Semaphore Isolation

Semaphore Isolation

  • Circuit Breaker 1개당 1개의 Semaphore 생성
  • Semaphore 별로 최대 동시 요청 개수 지정
  • 최대 개수 초과 시 Semaphore Rejection 발생 - Fallback 실행
  • Command를 호출한 Caller Thred에서 메소드 실행
  • Timeout이 제 시간에 발생하지 못함

Hystrix - Thread Isolation

Thread Isolation

  • Circuit Breaker 별로 사용할 Thread Pool을 지정(ThreadPoolKey)
  • Circuit Breaker : Thread Pool = N : 1 관계 가능
  • 최대 개수 초과 시Thread Pool Rejection 발생 - Fallback 실행
  • Command를 호출한 Thread가 아닌 Thread Pool에서 메소드 실행
  • 실제 메소드의 실행은 다른 Thread에서 실행되므로 Thread Local 사용 시 주의 필요

6. Ribbon

 

Ribbon 구조

모놀리식 시스템에서는 부하 분산을 위해 L4 스위치 같은 하드웨어 장비를 앞단에 두고 트래픽을 여러 서버로 분산하였습니다. 이렇게 중앙 집중화된 방식은 로드 밸런서에 장애가 발생하면 전체 서비스에 문제가 생기는 위험을 동반합니다. 또한 동적으로 서버가 추가, 삭제되는 환경에서 하드웨어 장비로 대응하는 것도 한계가 있습니다. 넷플릭스는 소프트웨어로 구현한 클라이언트 로드밸런서인 Ribbon을 추가했습니다. 여기서 클라이언트의 의미는 PC나 모바일 단말기가 아닌 MSA에서 다른 서비스를 호출하는 클라이언트 서비스를 뜻합니다.

 

Spring Cloud에서는 Ribbon클라이언트를 사용자가 직접 사용하지 않습니다.

=> Spring Cloud의 HTTP 통신이 필요한 요소에 내장되어 있습니다.

  • Zuul API Gateway
  • RestTemplate(@LoadBalanced)
  • Spring Cloud Feign - 선언적 Http Client

Ribbon이 기존 Load Balancer와 다른점

- Ribbon은 대부분의 동작은 Programmable합니다.

- Spring Cloud에서는 아래와 같은 BeanType으로

  • IRule - 주어진 서버 목록에서 어떤 서버를 선택할 것인가
  • IPing - 각 서버가 살아있는 가를 검사
  • ServerList<Server> - 대상 서버 목록 제공
  • ServerListFilter<Server> - 대상 서버들 중 호출할 대상 Filter
  • ServerListUpdater
  • IClientConfig
  • ILoadBalancer

7. Eureka

 

Eureka 구조

 

MSA 구조에서 서비스들은 동적으로 확장되고 축소되기도 하는데 이때마다 운영자가 일일이 인스턴스 정보를 수정, 관리하기란 쉬운일이 아닙니다. 따라서 인트턴스의 상태를 동적으로 관리하는 서버가 필요해졌는데 이를 보통 서비스 디스커버리 서버로 칭하며 넷플릭스는 Eureka라는 이름으로 공개하였습니다.

 

새로운 인스턴스는 시작할 때 Eureka 서버에 IP, 호스트 주소, 포트 정보 등을 스스로 전송합니다. Eureka 서버는 받은 정보를 가지고 일정한 간격으로 상태를 체크하면서 해당 인스턴스를 관리합니다. 인스턴스가 새로 실행될 때마다 자신의 정보를 서버에 동적으로 등록하기 때문에 운영자들은 서비스를 수평 확장할 때 IP 정보에 대해 신경 쓸 필요가 없어졌습니다. (여기서 수평 확장이란 부하가 걸린 서비스에 인스턴스를 늘려 처리량을 높이는 것을 의미합니다.) 운영자들은 설정 파일에 Eureka 서버 정보만 입력하면 되고, 서비스들은 다른 서비스를 호출할 때 Eureka 서버에 등록된 인스턴스를 조회하면 됩니다.

 

Netflix가 만든 Dynamic Service Discovery

  • 등록 : 서버가 자신의 서비스 이름(종류)와 IP 주소, 포트를 등록합니다.
  • 조회 : 서비스 이름(종류)을 갖고 서버 목록을 조회합니다.

Eureka가 Enable된 Spring Cloud Application은

  • Server 시작 시 Eureka 서버에 자동으로 자신의 상태 등록(UP)합니다.
  • 주기적 HeartBeat으로 Eureka Server에 자신이 살아 있음을 알림해줍니다.
  • Server 종료 시 Eureka 서버에 자신의 상태 변경(Down) 혹은 자신의 목록 삭제합니다.
  • Eureka상에 등록된 이름은 'spring.application.name'

Eureak + Ribbon in Spring Cloud

하나의 서버에 Eureka Client와 Ribbon Client가 함께 설정되면 Spring Cloud는 다음의 Ribbon Bean을 대체

 

  • ServerList<Server>

 - 기본 : ConfigurationBasedServerList

 - 변경 : DiscoveryEnabledNIWSServerList

 

  • IPing

 - 기본 : DummyPing

 - 변경 : NIWSDiscoveryPing

 

서버의 목록을 설정으로 명시하는 대신 Eureka를 통해서 Look Up해오는 부분을 구현합니다.

 

7. API Gateway

 

MAS 환경에서 API Gateway의 필요성

  • Single Endpoint제공 (API를 사용할 Client들은 API Gateway 주소만 인지)
  • API의 공통 로직 구현 (Logging, Authentication, Authorization)
  • Traffic Control (API Quota, Throttling)

 

참고사이트

https://www.youtube.com/watch?v=J-VP0WFEQsY

Comments