Deep Dive into Hystrix, Ribbon, Eureka
Hystrix
Netflix가 만든 Fault Tolerance Library
- 장애 전파 방지 & Resilience
기능적 관점에서 본 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
- 실패한 경우(Exception) 사용자가 제공한 메소드를 대신 실행한다
- Fallback
- 특정시간 동안 메소드가 종료되지 않는 경우 Exception을 발생시킨다
- Timeout
Hystrix - Circuit Breaker
- (1)일정시간 동안 (2)일정 개수 이상의 호출이 발생한 경우, (3)일정 비율 이상의 에러가 발생하면
- Circuit Open(호출차단)
- (4)일정 시간 경과 후에 단 한개의 요청에 대해서 호출을 허용하며 (Half Open), 이 호출이 성공하면
- Circuit Close(호출허용)
hystrix.command.<commandKey>.
metrics.rollingStats.timeInMilliseconds
- Default 10초circuitBreaker.requestVolumeThreshold
- Default 20개circuitBreaker.errorThresholdPercentage
- Default 50%circuitBreaker.sleepWindowInMilliseconds
- Default 5초
10초간 20개 이상의 호출이 발생한 경우, 50% 이상의 에러가 발생하면 5초간 Circuit Open
Hystrix - Circuit Breaker의 단위
Hystrix Circuit Breaker는 한 프로세스 내에서 주어진 CommandKey 단위로 통계를 내고 동작한다
- 즉, Circuit Breaker는 CommandKey 단위로 생성된다
@HystrixCommand(commandKey = "ExtDep1")
public String anyMethodWithExternalDependency1() {
// 추천 서버 호출 - 상품 추천 #1
}
@HystrixCommand(commandKey = "ExtDep1")
public String anyMethodWithExternalDependency2() {
// 추천 서버 호출 - 상품 추천 #2
}
동일한 Dependency를 갖는 Hystrix Command들을 동일한 CommandKey로 묶는 것을 고려해야 함
Hystrix - Fallback
Fallback으로 지정된 메소드는 다음의 경우에 원본 메소드 대신 실행된다
- Circuit Open
- Any Exception (HystrixBadRequestException 제외)
- Semaphore / ThreadPool Rejection (나중 Isolation에서 설명)
- Timeout
@HystrixCommand(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이 실행되어, 개발과정에 오류를 인지하지 못할 수 있다
Hystrix - Timeout
Hystrix에서는 Circuit Breaker 단위로 (CommandKey 단위로) Timeout을 설정할 수 있다
hystrix.command.<commandKey>.execution.isolation.thread.timeoutInMilliseconds
- Default 1초
Circuit Breaker의 Timeout 사용시 주의 사항
- Semaphore Isolation인 경우 - 제 시간에 Timeout이 발생하지 않는 경우가 대부분이다
- Default 값이 매우 짧다 - 1초
Hystrix - Isolation
두가지 Isolation 방식을 Circuit Breaker별로 지정 가능
- Semaphore
- Thread(default)
Hystrix - Semaphore Isolation
- Circuit Breaker 1개당 1개의 Semaphore 생성
- Semaphore별로 최대 동시 요청 개수 지정
- 최대 개수 초과시 Semaphore Rejection 발생 - Fallback 실행
- Command를 호출한 Caller Thread에서 메소드 실행
*Timeout이 제 시간에 발생하지 못함
Hystrix - Thread Isolation
- Circuit Breaker 별로 사용할 Thread Pool을 지정 (ThreadPoolKey)
- Circuit Breaker:Thread Pool = N:1 관계 가능
- 최대 개수 초과시 Thread Pool Rejection 발생 - Fallback 실행
- Command를 호출한 Thread가 아닌 Thread Pool에서 메소드 실행
실제 메소드의 실행은 다른 Thread에서 실행되므로 Thread Local 사용 시 주의 필요
Ribbon
Netflix가 만든 Software Load Balancer를 내장한 RPC(REST) Library
- Client Load Balancer with HTTP Client
Ribbon in Spring Cloud
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>
- 대상 서버들 중 호출할 대상 FilterServerListUpdater
IClientConfig
ILoadBalancer
Eureka
Netflix가 만든 Dynamic Service Discovery
- 등록: 서버가 자신의 서비스 이름(종류)와 IP주소 포트를 등록
- 조회: 서비스 이름(종류)을 갖고 서버 목록을 조회
Eureka in Spring Cloud
Eureka가 Enable된 Spring Cloud Application은
- Server 시작으로 Eureka 서버에 자동으로 자신의 상태 등록(UP)
- 주기적으로 HeartBeat으로 Eureka Server에 자신이 살아 있음을 알림
- Server 종료시 Eureka 서버에 자신의 상태 변경(DOWN) 혹은 자신의 목록 삭제
- Eureka 상에 등록된 이름은
spring.application.name
Eureka + Ribbon in Spring Cloud
하나의 서버에 Eureka Client와 Ribbon Client가 함께 설정되면
Spring Cloud는 다음의 Ribbon Bean을 대체
1. ServerList<Server>
- 기본: ConfigurationBasedServerList
- 변경: DiscoveryEnabledNIWSServerList
2. IPing
- 기본: DummyPing
- 변경: NIWSDiscoveryPing
서버의 목록을 설정으로 명시하는 대신 Eureka를 통해서 Look Up 해오는 구현
이 세가지를 잘 적용하면 MSA 환경에서 Server 들간의 통신이 큰 문제없이 잘 될 것 같다는 생각...
'SpringCloud' 카테고리의 다른 글
[11번가 Spring Cloud 기반 MSA로의 전환] 4. 장애 시나리오 (0) | 2021.02.08 |
---|---|
[11번가 Spring Cloud 기반 MSA로의 전환] 3. Hystrix, Ribbon, Eureka 적용 in 11st (0) | 2021.02.08 |
[11번가 Spring Cloud 기반 MSA로의 전환] 1. 왜 MSA 를 도입하는지 어떻게 MSA를 도입할 것인지? (0) | 2021.02.08 |
[Spring Cloud 를 활용한 MSA 기초] 9. Configuration Server, Tracing.Monitaring, 그리고 남은 이야기 (0) | 2021.02.07 |
[Spring Cloud 를 활용한 MSA 기초] 8. API Gateway - Zuul (0) | 2021.02.07 |
댓글