나의 개발 일상 기록
[MSA] Hystrix, Ribbon, Eureka in Spring Cloud Zuul 본문
Spring Cloud Zuul
Spring Cloud Zuul은 API Routing을 Hystrix, Ribbon, Eureka를 통해서 구현합니다.
- Spring Cloud와 가장 잘 Integration 되어있는 API Gateway
1. Zuul

API 요청 들은 각각 HystrixCommand를 통해서 실행되며, 각 API의 Routing은 Ribbon & Erueka의 조합으로 수행합니다.
Spring Cloud Zuul에서 Hystrix Commandkey는
- 각 서버군 이름 (Zuul 용어로 Service Id, Eureka에 등록된 서버군 이름)이 사용 됩니다.
- 앞선 그림을 예를 들면 3개의 CommandKey가 사용됩니다.
ex) hystrix.command.[product | display | member].xxxx
2. Hystirx Isolation in Spring Cloud Zuul
- Spring Cloud Zuul에서 Hystrix Semaphore Isolation

- Semaphore Isolation을 기본으로 합니다.
=> 특정 API군의 장애(지연)등이 발생하여도 Zuul 자체의 장애로 이어지지 않습니다.
- Hystrix의 원래 Default는 Thread Isolation 입니다.
- Spring Cloud Zuul에서 Hystrix Thread Isolation

Thread Isolation
- Hystrix Timeout을 통해서 특정 서버군의 장애시에도 Zuul의 Container Worker Thread의 원활한 반환을 합니다.
<변경 방법>
zuul :
ribbon-isolation-strategy : thread
Spring Cloud Zuul의 Hystrix Isolation을 Thread로 바꾸면
- Server 전체에 한개의 Thread Pool이 생겨버리게 구현됩니다.
- 'RibbonCommand'라는 이름의 Thread Pool
=> 서버군(Service ID)별로 Thread Pool을 분리해주는 것이 필요하다는 팀의 판단이 있어야 합니다.
=> Spring Cloud Netflix 프로젝트에 Pull Request를 통해 해당 코드 수정
zuul:
threadPool:
useSeparateThreadPools : true
threadPoolKeyPrefix : zuulgw

3. Server to Server 호출 in MSA
MSA 플랫폼 외부의 호출은 API Gateway를 단일 창구로 사용합니다.

MSA 서버에서는 Gateway를 통해 API를 호출하는 방식(왼쪽 그림)보다는 API를 직접 호출하는 방식(오른쪽 그림)을 추구합니다. 왼쪽 그림의 방식은 모든 API 호출을 통제할 수 있다는 장점이 있지만 만약 Gateway가 죽게 된다면 모든 통신을 죽게 됩니다. 또한 MSA서버가 엄청나게 많아지게 되면 엄청난 트래픽이 발생하는 단점을 가지고 있습니다.
- API를 직접 호출하는 방식에서 상대방의 서버 목록을 아는 방법
- Ribbon + Eureka 조합으로 Peer to Peer 호출
Spring Cloud에서는 다음의 Ribbon + Eureka 기반의 Http 호출 방법을 제공합니다.
- @LoadBalanced RestTemplate
* @LoadBalanced주석을 붙이는 경우 RestTemplate이 Ribbon + Eureka 기능을 갖게 됩니다.
* RestTemplate이 Bean으로 선언된 것만 적용 가능합니다.
- Spring Cloud Feign
4. Spring Cloud Feign
- Java Interface + Spring MVC Annotation 선언으로 Http 호출이 가능한 Spring Bean을 자동 생성됩니다.
- OpenFeign기반의 Spring Cloud 확장됩니다.
- Hystrix + Ribbon + Eureka와 연동되어있습니다.
- Spring Cloud Feign with Eureka and Ribbon
Ribbon + Eureka 없이 사용하기
@FeignClient(name = "product", url = "http://localhost:8081") // URL 직접 명시
public interface FeignProductRemoteService{
@RequestMapping(path = "/products/{productId}")
String getProductInfo(@PathVariable("productId") String productId)
}
Ribbon + Eureka 연동
@FeignClient(name = "product") // URL 생략
public interface FeignProductRemoteService{
@RequestMapping(path = "/products/{productId}")
String getProductInfo(@PathVariable("productId") String productId)
}
- Spring Cloud Feign with Hystrix
Hystrix 연동
- Hysrix가 Classpath에 존재
- feign.hystrix.enabled = true
- Spring Cloud Feign 사용 시 주의 사항
Cricuit Breaker의 단위랑 Thread Pool의 단위가 메서드 단위로 잘게 분해되기 때문에 커스텀한 코드나 설정을 통해서 비슷한 유형의 메서드는 같은 Cricuit Breaker를 사용하도록 조정해야합니다.
- Spring Cloud Feign with Hystrix, Ribbon, Eureka
- 호출하는 모든 메소드는 Hystrix Command로 실행합니다.
* Circuit Breaker, Timeout, Isolation, Fallback 적용
- 호출할 서버는 Eureka를 통해 얻어서, Ribbon으로 Load Balancing되어 호출됩니다.
5. 장애 유형별 동작 예
- 특정 API 서버의 인스턴스 한개 DOWN된 경우(3개 중 1개 DOWN)
Eureka - Heartbeat 송신이 중단 됨으로 일정 시간 후 목록에서 사라집니다.
Ribbon - IOException이 발생한 경우 다른 인스턴스로 Retry합니다.
Hystrix - Circuit은 오픈되지 않음 (Error=33%) Fallback, Timeout은 동작합니다.
* Error가 50% 이상인 경우 Circuit 오픈됩니다.
- 특정 API가 비정상 동작하는 경우(지연, 에러)
Hystrix - 해당 API를 호출하는 Circuit Breaker 오픈 Fallback, Timeout도 동작합니다.
* Spring Cloud Config
Git기반의 Config 관리 플랫폼 내의 모든 Server들은 Config Client를 탑재합니다. 서버 시작 시 Config 서버가 제공하는 Config들이 PropertySource로 등록됩니다.

Git Repository내의 Config 파일들은 다양하게 구성이 가능합니다.
- 전체 서버 공통 Config
- 서버군용 Config
- 특정 서버용 Config
참고사이트
https://www.youtube.com/watch?v=J-VP0WFEQsY&t=1955s
'MSA' 카테고리의 다른 글
| [MSA] Hystrix Monitoring With Turbine (0) | 2021.07.22 |
|---|---|
| [MSA] MSA 운영 환경을 위한 전용 모니터링 도구 (0) | 2021.07.21 |
| [MSA] Spring Cloud Netflix (0) | 2021.07.14 |
| [MSA] MSA(Microservices Architecture) (0) | 2021.07.12 |