Hystrix, Ribbon, Eureka 적용 in 11st
API Gateway
MSA 환경에서 API Gateway의 필요성
- Single Endpoint 제공
- API를 사용할 Client들은 API Gateway 주소만 인지
- API의 공통 로직 구현
- Logging, Authentication, Authorization
- Traffic Control
- API Quota, Throttling
자체 개발 Vs Zuul
SK planet은 자체 개발 API Gateway를 상용 운영 중
- 11번가를 제외한 서비스의 Open API 제공
- Node.js / Koa Framework 기반
- 100% 자체 개발 from Scratch
- Logging, Authorization, Throtting 등..
100% 자체 개발한 API Gateway를 두고 Zuul을 도입해야 할까?
Spring Cloud Zuul
Spring Cloud Zuul은 API Routing을 Hystrix, Ribbon, Eureka를 통해서 구현
- Spring Cloud와 가장 잘 Integration 되어있는 API GateWary
Hystrix, Ribbon, Eureka in Spring Cloud Zuul
API 요청들은 각각 HystrixCommand를 통해서 실행되며,
각 API의 Routing은 Ribbon & Eureka의 조합으로 수행
Hystrix Circuit Breaker in Spring Cloud Zuul
Reminder
- Hystrix Circuit Breaker는 CommandKey 이름 단위로 동작한다
Spring Cloud Zuul에서 Hystrix CommandKey는
- 각 서버군 이름 (Zuul 용어로 Service ID, Eureka에 등록된 서버군 이름)이 사용됨
- 앞선 그림을 예를 들면 3개의 CommandKey가 사용
HystrixCommand('product')
HystrixCommand('display')
HystrixCommand('member')
Histrix의 옵션을 서버군(Service ID)별로 부여 가능
hystrix.command.[product|display|member].
metrics.rollingStats.timeInMilliseconds
- Default 10초circuitBreaker.requestVolumeThreshold
- Default 20개circuitBreaker.errorThresholdPercentage
- Default 50%circuitBreaker.sleepWindowInMilliseconds
- Default 5초
Hystrix Isolation in Spring Cloud Zuul
Reminder
- Hystrix Isolation은 Semaphore/Thread 두가지 모드가 있으며, Semaphore는 CommandKey단위로
ThreadPool은 별도 부여된 ThreadPoolkey 단위로 생성된다
Spring Cloud Zuul에서 Histrix Isolation은
- Semaphore Isolation을 기본으로 한다
- Hystrix의 원래 Default는 Thread Isolation
Spring Cloud Zuul의 기본설정으로는 Semaphore Isolation
- 특정 API 군의 장애(지연)등이 발생하여도 Zuul 자체의 장애로 이어지지 않음
Spring Cloud Zuul에서 우리는 Thread Isolation을 사용하고 싶다는 생각...
Thread Isolation을 통해서
- Hystrix Timeout을 통해서 특정 서버군의 장애시에도 Zuul의 Container Worker Thread의 원할한 반환
zuul:
rebbon-isolation-strategy: thread
Spring Cloud Zuul의 Histrix Isolation을 Thread로 바꾸면
- Server 전체에 한개의 Thread Pool이 생겨버리게 구현
- 'RibbonCommand'라는 이름의 Thread Pool
이건 우리가 원하던 모습이 아니다!
- 서버군(Service ID)별로 Thread Pool을 분리해주는 것이 필요하다는 팀의 판단
- Spring Cloud Netflix 프로젝트에 Pull Request를 통해 해당코드 수정
zuul:
threadPool:
useSeparateThreadPools: true
threadPoolKeyPrefix: zuulgw
Server to Server 호출 in MSA
MSA 플랫폼 외부의 호출은 API Gateway를 단일 창구로 사용
MSA 플랫폼 내부의 API Server 간의 호출은 어덯게 할것인가?
Gateway 경우 모델
- 장점
- 모든 API 호출을 한곳에서 통제할 수 있다
- 각 API서버가 다른 API서버의 주소를 알 필요가 없다
- 단점
- 불필요한 Network Hop/부하가 생긴다
- API GW가 SPOF가 될 수 있다
Peer to Peer 호출
- 장점
- Server간의 호출이 별도의 Hop/부하가 없다
- API Server간의 호출이 많아질 수록 유리하다
- 단점
- API 호출을 한곳에서 모두 통제할 수 없다
- 모든 API서버가 다른 API서버의 주소를 알아야 한다 -> Eureka가 해결 가능
Ribbon + Eureka 조합으로 Peer to Peer 호출을 하기로 결정
Spring Cloud에서는 다음의 Ribbon + Eureka 기반의 Http 호출 방법을 제공
@LoadBalanced RestTemplate
@LoadBalanced
주석을 붙이는 경우 RestTemplate가 Ribbon + Eureka 기능을 갖게 됨- RestTemplate이 Bean으로 선언된 것만 적용가능
- Spring Cloud Feign
Spring Cloud Feign
Declarative Http Client
- Java Interface + Spring MVC Annotation 선언으로 Http 호출이 가능한 Spring Bean을 자동 생성
- OpenFeign기반의 Spring Cloud 확장
- Hystrix + Ribbon + Eureka와 연동되어 있음
Spring Cloud Feign with Eureka and Ribbon
Ribbon + Eureka 없이 사용하기
URL 직접 명시
@FeignClient(name = "product", url = "http://localhost:8081") // URL 직접 명시
public interface FeignProductRemoteService {
@RequestMapping(path = "/products/{productId}")
String getProductInfo(@PathVariable("productId") String productId);
}
Ribbon + Eureka 연동
URL 생략
@FeignClient(name = "product") // URL 생략
public interface FeignProductRemoteService {
@RequestMapping(path = "/products/{productId}")
String getProductInfo(@PathVariable("productId") String productId);
}
Spring Cloud Feign with Hystrix
Hystrix 연동하기
- Hystrix가 Classpath에 존재
feign.hystrix.enabled=true
Default Hystrix Key
- CommandKey: 각 메소드 단위로 생성
- ex)
FeignProductRemoteService#getProductInfo(String)
- 메소드 단위로 Circuit Breaker 생성
- ex)
- ThreadPoolKey: 서버군 별로 생성
- ex) product
- Feign에서는 CommandGroupKey를 설정한, ThreadPoolKey가 명시되지 않는 경우 CommandGroupKey가 대신 사용
Hystrix 규칙 Customizing 하기
- Feign Interface별로 Configuration 클래스 지정가능
- Hystrix Key 및 속성을 지정할 수 있는 SetterFactoryBean 선언 가능
11번가의 Feign Hystrix Key 정책
- CommandKey: 기본 정책에서 파라메터 제거
- ex)
FeignProductRemoteService#getProductInfo
- ex)
- ThreadPoolKey:
<Caller서버군 이름>-<Callee서버군 이름>
- ex) display-product
- 자체 Annotation으로 위 속성 임의 변경 가능
Spring Cloud Feign with Hystrix, Ribbon, Eureka
- 호출하는 모든 메소드는 Hystrix Command로 실행
- Circuit Breaker, Timeout, Isolation, Fallback 적용
- 호출할 서버는 Eureka를 통해 얻어서, Ribbon으로 Load Balancing되어 호출
'SpringCloud' 카테고리의 다른 글
[11번가 Spring Cloud 기반 MSA로의 전환] 5. 11번가 MSA 환경 구성 (0) | 2021.02.08 |
---|---|
[11번가 Spring Cloud 기반 MSA로의 전환] 4. 장애 시나리오 (0) | 2021.02.08 |
[11번가 Spring Cloud 기반 MSA로의 전환] 2. Deep Dive into Hystrix, Ribbon, Eureka (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 |
댓글