이 글은 2019년에 작성된 본인 소유의 네이버 블로그에서 이동해 왔습니다.
Cloud Native Application 구축을 위해 최근 가장 각광 받고 있는 기술이 MSA(Micro Service Architecture)입니다. MSA의 핵심이 되는 기술들로는 회로차단, 로드밸런스, 서비스레지스트리, APIGateway등이며 이런 필요 기능등을 Open Source로 배포하는 가장 유명한 소프트웨어가 아마존 AWS 환경하에서 MSA를 성공적으로 구축해서 사용하고 있는 Netflex의 OSS(Open Source Software) 입니다. Netfliex OSS 라이브러리에는 여러 기능들이 있으나 이중 Hystrix, Eureka, Ribbon, Zuul등은 Pivotal社가 배포하는 Spring Cloud에서 차용해서 사용하고 있습니다.
※APIGateway로 유명한 제품으로는 Kong, Google Apigee, Amazon API Gateway, IBM API Connect, CA API Gateway등 다양한 제품들이 있습니다.
Netflix OSS는 다음과 같은 특징이 있습니다.
- Netflix가 진행한 50개 이상의 사내 프로젝트를 오픈소스로 공개
- Netflix가 운영되는 플랫폼(AWS) 안의 여러 컴포넌트와 자동화 도구를 사용하면서 파악한 패턴과 해결 방법들을 블로그, 오픈소스 등으로 공개
Spring Cloud와 Netflix OSS
개인적으로 Netflix OSS가 MSA로 국내에서 각광받는 가장 큰 이유는 Netflix OSS가 java기반이며 Spring Cloud에서 Netflix OSS의 Histrix, Zuul, Eureka, Ribbon를 랩핑해서 사용하고 있기 때문이라고 봅니다. 두 라이브러리간의 관계를 집합으로 표시하면 다음과 같습니다.
Histrix(Circuit Breaker)
“Failure as a First Class Citizen”: 마이크로서비스 내에서 장애는 아주 일상적인 것이 될 수 있기 때문에 이에 대한 대응을 하기 위해 나온 개념
- Circuit Breaker란
서킷브레이커 즉 회로차단기는 전기 기기에서 과부하나 과전류가 들어왔을 때 메인 기기를 보호하기 위해 흔히 쓰는 회로 차단기를 말합니다. 또한 주가 등락 폭이 심하게 요동칠 때도 시장 과열을 방지하기 위해 서킷 브레이커를 가동해 거래를 중지 시키기도 합니다. MSA에서 서킷 브레이커는 특정 MSA 서비스의 장해로 인해 다른 MSA 서비스에도 장해를 일으킬 수 있는 가능성을 방지하기 위해 사용합니다.
* Latency Tolerance and Fault Tolerance for Distributed Systems
- Circuit Breaker로써 Histrix
Histrix는 Netflix가 Amazon AWS 클라우드 상에서 MSA를 구축 운영한 노하우를 OSS(Open Source Software)로 전환해 배포하고 있는 Netflix OSS 중 Java에서 사용 할 수 있는 Circuit Breaker 입니다.(앞서 설명했듯이 Spring Cloud에서는 Histrix를 Wrapping해서 사용하고 있습니다.)
대표사진 삭제
[Circuit Breaker 작동]
Hystrix의 대표 기능
1. Thread timeout, 장애 대응 등을 설정해 장해시 정해진 루트를 따르도록 할 수 있다.
2. 미리 정해진 임계치를 넘으면 장해가 있는 로직을 실행하지 않고 우회 하도록 할 수 있다.
Netflix Histrix 사용법
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
- 1행 선택1행 다음에 행 추가
셀 전체 선택
열 너비 조절
행 높이 조절
요약 |
1. spring-cloud-starter-netflix-hystrix 라이브러리 추가 2. Main Application에 @EnableCircuitBreaker annotation 추가 3. Circuit Break를 추가하고자 하는 메소드에 @HystrixCommand annotation추가 |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
1. 사용하는 Java Project의 Dependency에 Histrix 라이브러리 추가
Ex: gradle의 경우)
dependencies {
compile('org.springframework.boot:spring-boot-starter-web')
testCompile('org.springframework.boot:spring-boot-starter-test')
...
compile('org.springframework.cloud:spring-cloud-starter-netflix-hystrix')
}
2. Java 클래스에 @HystrixCommand를 통해 서비스 연동 메소드를 Histrix에 연결
Server#1.java
…
@Service
public class XXXX {
private String URL = “http://yourip:yourport/otherservie/”; // MSA로 연결할 대상 서비스의 RESTFul
…
// @HystrixCommand를 이용해 다른 서비스와의 연동을 Hystrix에 등록한다.
// 이때 실패하게 되면 doFallbackProcess 메소드가 작동한다.
@HystrixCommand(fallbackMethod = "doFallbackProcess")
public String getOtherServiceMessage(String param) {
// 여기 예제에서는 원격지 RESTFul 통신을 위해 RestTemplate 클래스를 사용
return this.restTemplate.getForObject(url, String.class);
}
public String doFallbackProcess() {
return “Do your fall back process”;
}
}
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
- 1행 선택1행 다음에 행 추가
- 2행 선택2행 다음에 행 추가
셀 전체 선택
열 너비 조절
행 높이 조절
@HystrixCommand |
@HystrixCommand(fallbackMethod = " doFallbackProcess") public String getOtherServiceMessage(String param) { // 여기 예제에서는 원격지 RESTFul 통신을 위해 RestTemplate 클래스를 사용 return this.restTemplate.getForObject(url, String.class); } |
HystrixCommand annotation이 실행될 때 마다, - 실행된 결과의 성공/실패 여부를 기록하고 Hystrix 서버에 통계 표시 - 실행 결과 통계(설정된 임계치)에 따라 Circuit Open을 판단하고 미리 정해진 Exception 룰을 따르도록 함 - Hystrix Circuit Open 기본 값은 : 10초 동안 20개 이상의 호출이 발생 했을 때 50% 이상의 호출에서 에러가 발생했을 때 작동하도록 설정되어 있음 |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
- 1행 선택1행 다음에 행 추가
- 2행 선택2행 다음에 행 추가
셀 전체 선택
열 너비 조절
행 높이 조절
@HystrixProperty |
@HystrixCommand(commandKey = "commandKeyExample", fallbackMethod = "doFallbackProcess", commandProperties = { @HystrixProperty(name=”execution.isolation.thread.timeoutInMilliseconds”,value=”2000”) } ) public String getOtherServiceMessage(String param, Throwable t) { // Throwable 을 받아 에러 처리를 할 수 있습니다. // 여기 예제에서는 원격지 RESTFul 통신을 위해 RestTemplate 클래스를 사용 return this.restTemplate.getForObject(url, String.class); } // fallback method 구현 public String doFallbackProcess(Throwable t) { return “Do your fall back process”; } |
- commandKey를 이용해 Hystrix에 대한 속성을 여러 개 설정하고자 할 때 각 속성별로 그룹을 지어 다른 속성을 부여할 수 있습니다. 이에 대한 내용은 아래에 설명 추가 하도록 하겠습니다. - @HystrixProperty는 HystrixCommand를 실행시킬 때 Hystrix를 구동할 조건을 입력하는 프로퍼티 입니다. - execution.isolation.thread.timeoutInMilliseconds 옵션은 @HystrixProperty annotation이 붙은 메소드의 Thread Timeout을 설정하는 Property입니다. 기본값은 1000ms이며 예제에서는 2000ms(2초)로 기본값을 변경했습니다. 이 설정이 입력되었을 때 예의 2초안에 메소드가 완료되지 않는다면 설정된 예외(Fallback)를 처리하게 됩니다. - timeoutInMilliseconds는 Thread의 Execute 시간이 올래 걸리는 업무 처리에 유용(DB 처리등) |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
대표사진 삭제
[Hystrix Flow Chart]
*이미지출처: http://www.lordofthejars.com/2014/09/defend-your-application-with-hystrix.html
3. Start Application에 @EnableCircuitBreaker Annotation 추가
SpringBoot등을 사용한다면 SpringBoot를 Invocation 시키는 Application에 @EnableCircuitBreaker Annotation을 추가 하도록 합니다.
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
셀 전체 선택
열 너비 조절
행 높이 조절
… import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker; @SpringBootApplication @EnableCircuitBreaker public class YourApplication { public static void main(String[] args) { SpringApplication.run(YourApplication.class); } } |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
Hystrix 설정 변경
Hystrix는 앞서 설명했듯이 임계 값, Thread Timeout milliseconds등에 대한 기본값이 설정되어 있습니다. 프로젝트의 성격이나 어플리케이션의 성격에 따라 해당 값에 대한 수정이 필요합니다.
SpringBoot를 이용한 Hystrix 사용시 이에 대한 설정은 application.yml(혹은 application.properties) 파일에서 하게 됩니다.
설정 예)
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
셀 전체 선택
열 너비 조절
행 높이 조절
hystrix: command: commandKeyExample1: # key명을 default로 입력하면 모든 hystrix command 기본 값으로 설정됩니다.(#여기선 개별 설정) execution: isolation: thread: timeoutInMilliseconds: 3000 # commandKey설정을 통해 HystrixCommand의 Property를 속성파일에서 변경 할 수 있습니다. |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
HystrixCommand.[keyvalue].execution.isolation.thread.timeoutInMilliseconds=3000
Hystrix Circuit Breaker 작동
Hystrix Command Property로 지정한 임계치(Circuit Breaker)에 도달하면 HystrixCommand가 지정된 메소드는 하위 메소드를 try하지 않고 미리 예외처리 로직을 타게 됩니다.
사용법은 @HysterixProperty를 이용해 지정하거나 application.yml 파일을 통해 설정할 수 있습니다.
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
- 1행 선택1행 다음에 행 추가
- 2행 선택2행 다음에 행 추가
셀 전체 선택
열 너비 조절
행 높이 조절
@HystrixProperty |
@HystrixCommand(fallbackMethod = "fallback", commandProperties = { … @HystrixProperty(name = “metrics.rollingStats.timeInMilliseconds”, value = “10000”), @HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value = "10"), @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "5"), @HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds", value = "5000") }) |
- metrics.rollingStats.timeInMilliseconds : 서킷 브레이커가 열리기 위한 조건을 체크하는 시간입니다. 서킷 브레이커와 관련된 몇가지 조건들과 함께 조건을 정의하게 되는데 "10초간 50% 실패하면 서킷 브레이커 발동" 이라는 조건이 정의 되어있다면 여기서 10초을 설정합니다. 기본값은 10초(10000)입니다. - circuitBreaker.errorThresholdPercentage : 서킷 브레이커가 작동하게 될 에러 퍼센트를 지정합니다. 기본값은 50(50%)입니다. - circuitBreaker.requestVolumeThreshold : 서킷 브레이커가 열리기 위한 최소 요청 조건 입니다. 즉 이 값이 20으로 설정 되어있다면 10초간 19개의 요청이 들어와서 19개가 전부 실패하더라도 서킷 브레이커는 열리지 않게 됩니다. 기본값은 20입니다. - circuitBreaker.sleepWindowInMilliseconds : 서킷 브레이커가 열렸을 때 얼마나 지속될지를 설정합니다. 기본값은 5초(5000)입니다. - 5초후 서킷 브레이커는 다시 카운트1부터 시작 |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
* application.yml에서는 다음과 같이 설정합니다.
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
셀 전체 선택
열 너비 조절
행 높이 조절
… hystrix: command: exampleCommandKey1: execution: isolation: thread: timeoutInMilliseconds: 2000 circuitBreaker: requestVolumeThreshold: 3 errorThresholdPercentage: 50 … |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
Hystrix Propery
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
- 1행 선택1행 다음에 행 추가
셀 전체 선택
열 너비 조절
행 높이 조절
@HystrixCommand(fallbackMethod = "fallback", commandProperties = { @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "500"), @HystrixProperty(name = "metrics.rollingStats.timeInMilliseconds", value = "10000"), @HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value = "10"), @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "5"), @HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds", value = "10000") }, threadPoolProperties = @HystrixProperty(name = "coreSize", value = "100")) |
- execution.isolation.thread.timeoutInMilliseconds Hystrix 가 적용된 메서드의 타임아웃 지정. 이 타임아웃 내에 메서드가 완료되지못하면 서킷브레이커가 닫혀있다고 하더라도 fallback 메서드가 호출됨. 보통 외부 API 를 호출하게되면 RestTemplate 과 같은 http client에도 connect, read timeout 등을 지정하게하는데 hystrix timeout은 이를 포함하고 여유를 좀 더 두어 잡는게 유리. 기본값은 1초(1000) - metrics.rollingStats.timeInMilliseconds 서킷 브레이커가 열리기위한 조건을 체크할 시간입니다.서킷브레이커의 다른 몇가지 조건들과 함께 조건을 정의하게되는데 "10초간 50% 실패하면 서킷 브레이커 작동" 이라는 조건이 정의되어있다면 여기서에 10초를 입력되어 있다는 뜻. 기본값은 10초(10000) - circuitBreaker.errorThresholdPercentage 서킷 브레이커가 작동 할 에러 퍼센트를 지정합니다. 기본값은 50 - circuitBreaker.requestVolumeThreshold 서킷 브레이커가 열리기 위한 최소 요청 조건입니다. 즉 이 값이 20으로 설정되어있다면 10초간 19개의 요청이 들어와서 19개가 전부 실패하더라도 서킷 브레이커는 열리지 않습니다. 기본값은 20 - circuitBreaker.sleepWindowInMilliseconds 서킷 브레이커가 열렸을때 얼마나 지속될지를 설정합니다. 기본값은 5초(5000) - coreSize 위에서 별도의 설명은 안했는데 Hystrix 작동방식은 Thread를 이용하는 Thread 방식과 Semaphore 방식이 있습니다. Thread 를 이용할 경우 core size를 지정하는 속성입니다. 넷플릭스 공식 가이드에 의하면 Thread 방식을 권고.(디폴트 설정도 Thread 방식이다.) 기본 coreSize 는 10 |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
이번 포스팅은 여기까지 입니다.
실습은 Hystrix, Ribbon, Eureka, Zuul을 포함해 하나의 예제로 별도 포스팅 하겠습니다
감사합니다.
'Application Modernization > Service Mesh' 카테고리의 다른 글
istio와 envoy 란 (0) | 2021.09.05 |
---|---|
OpenFeign 간단 예제 (0) | 2021.09.01 |
OpenFeign 이란? (0) | 2021.09.01 |
Eureka : Service Discovery (0) | 2021.08.31 |
Ribbon : Load Balancer (0) | 2021.08.31 |