Circuit Breaker 패턴
Circuit Breaker가 왜 필요한가
외부 API 호출과 같은 remote call시, 호출 실패나 hang 등을 고려하지 않을 수 없습니다. 일시적이고 단발성인 오류는 적절히 timeout을 주고 오류를 try-catch 하면 되지만, 오류가 장시간 계속 발생할 때는 이런 방식으로 해결할 수 없는 경우가 발생합니다. 응답을 받지 못한 request가 timeout이 되는 시간까지 쓰레드풀이나 DB풀을 선점하고 있거나, 메모리를 잡아 먹으면서 점차 리소스는 부족해지고, 같은 리소스를 사용하고 있는 다른 부분들에도 순식간에 장애가 전파되기 시작합니다.
그렇다면 이런 문제를 해결하기 위해서는 어떻게 해야 될까요? 문제가 되는 두가지 조건 중 하나를 없애면 됩니다.
첫번째는, 오류가 전파되지 않도록 공유하고 있는 리소스를 분리하는 방법이고,
두번째는, 오류 발생시 오랫동안 리소스를 잡아두지 못하게 하는 방법입니다.
Circuit Breaker는 여기서 두번째 방법에 해당됩니다.
Circuit Breaker 패턴
Circuit breaker 패턴은 Release It에서 처음 소개된 패턴이고, 전기의 회로차단기에서 차용한 개념입니다. 회로가 close될때는 정상적으로 전기가 흐르다가 문제가 생기면 회로를 open하여 더이상 전기가 흐르지 않도록 한 것과 같이, 평소(Close state)에는 정상적으로 동작하다가, 오류 발생시(Open state) 더이상 동작하지 않도록 합니다. 이렇게 문제가 되는 기능 자체를 동작하지 않게 해서 리소스를 점유하지 않게 하는 겁니다.
물론 전류가 복구되면 다시 정상화 되는 회로차단기처럼, 기능이 복구되면 다시 서비스를 정상화시켜야 하는데요. 일정 시간이 지났다고 무작정 정상 상태(Close state)로 돌리면, request가 갑자기 몰리면서 문제가 다시 발생하겠죠. 그래서 일부 request만 실행해보면서 기능이 다시 정상적으로 동작하는지 확인하는 과정(Half open state)이 필요합니다. 그렇게 정상화되었다고 판단되면 다시 원래 상태로 복구하게 됩니다.
여기서 총 3가지 상태가 언급되었는데요. 정리해보면 아래와 같습니다.
정상 상태 : Close
오류 상태 : Open
반열림 상태 : Half Open
3가지 상태간의 전환은 아래와 같이 됩니다.
Circuit Breaker 구현
Circuit Breaker를 간단하게 구현해봅시다.Martin fowler의 Circuit Breaker의 코드를 조금 수정해서 javascript로 구현할께요. 먼저 3가지 상태를 정의합니다.
const State = Object.freeze({
Close : Symbol('close'),
Open : Symbol('open'),
HalfOpen : Symbol('half-open')
});
특정 기능을 wrapping하여 Close상태이면 정상적으로 동작하고, Open 상태이면 바로 error를 반환하는 함수를 추가합니다. Half Open인 경우 간단하게 랜덤하게 request를 실행할 수 있게 해봅시다.
call(command) {
switch (this.state()) {
case State.HalfOpen :
if (this.executeByRandom()) {
try {
command();
this.resetFailure();
} catch (e) {
// Continue Error
}
} else {
throw new Error("Error");
}
break;
case State.Close :
try {
command();
} catch (e) {
this.recordFailure();
throw e;
}
break;
case State.Open :
throw new Error("Error");
default :
throw new Error("Unknown State");
}
}
마지막으로 상태를 반환하는 기능만이 남았습니다. 10번 이상 오류가 발생하면 Open 상태가 되고, 1분마다 정상이 되었는지 확인하기 위해 Half Open 상태를 반환하는 함수를 만듭니다.
state() {
if (this.failureCount >= 10) {
if ((new Date().getTime() - this.lastFailureTime) > 1000 * 60){
return State.HalfOpen;
} else {
return State.Open;
}
} else {
return State.Close;
}
}
참고
- https://martinfowler.com/bliki/CircuitBreaker.html
- https://topswagcode.com/2016/02/07/Circuit-Breaker-Pattern/
Circuit Breaker Pattern
What is a circuit breaker? A circuit breaker is an automatically operated electrical switch designed to protect an electrical circuit from damage caused by Overcurrent/overload or short circuit. Its basic function is to interrupt current flow after Protect
topswagcode.com
Circuit breaker 패턴을 이용한 장애에 강한 MSA 서비스 구현하기 #1
Circuit breaker와 넷플릭스 Hystrix
조대협 (http://bcho.tistory.com)
MSA에서 서비스간 장애 전파
마이크로 서비스 아키텍쳐 패턴은 시스템을 여러개의 서비스 컴포넌트로 나눠서 서비스 컴포넌트간에 호출하는 개념을 가지고 있다. 이 아키텍쳐는 장점도 많지만 반대로 몇가지 단점을 가지고 있는데 그중에 하나는 하나의 컴포넌트가 느려지거나 장애가 나면 그 장애가난 컴포넌트를 호출하는 종속된 컴포넌트까지 장애가 전파되는 특성을 가지고 있다.
이해를 돕기 위해서 아래 그림을 보자
Service A가 Service B를 호출하는 상황에서 어떤 문제로 인하여 Service B가 응답을 못하거나 또는 응답 속도가 매우 느려진 상황이라고 가정하자. Service A가 Service B에 대한 호출 시도를 하면, Service A에서 Service B를 호출한 쓰레드는 응답을 받지 못하기 때문에, 계속 응답을 기다리는 상태로 잡혀있게 된다. 지속해서 Service A가 Service B를 호출을 하게 되면 앞과 같은 원리로 각 쓰레드들이 응답을 기다리는 상태로 변하게 되고 결과적으로는 남은 쓰레드가 없어서 다른 요청을 처리할 수 없는 상태가 된다.
이렇게 Service B의 장애가 Service A에 영향을 주는 경우를 장애가 전파 되었다고 한다. 이 상황에서 Service A를 호출하는 서비스가 또 있다면, 같은 원리로 인하여 그 서비스까지 장애가 전파되서 전체 시스템이 장애 상태로 빠질 수 있다.
Circuit breaker 패턴
이런 문제를 해결하는 디자인 패턴이 Circuit breaker 라는 패턴이 있다.
기본적인 원리는 다음과 같다. 서비스 호출 중간 즉 위의 예제에서는 Service A와 Service B에 Circuit Breaker를 설치한다. Service B로의 모든 호출은 이 Circuit Breaker를 통하게 되고 Service B가 정상적인 상황에서는 트래픽을 문제 없이 bypass 한다.
.
만약에 Service B가 문제가 생겼음을 Circuit breaker가 감지한 경우에는 Service B로의 호출을 강제적으로 끊어서 Service A에서 쓰레드들이 더 이상 요청을 기다리지 않도록 해서 장애가 전파하는 것을 방지 한다. 강제적으로 호출을 끊으면 에러 메세지가 Service A에서 발생하기 때문에 장애 전파는 막을 수 있지만, Service A에서 이에 대한 장애 처리 로직이 별도로 필요하다.
이를 조금 더 발전 시킨것이 Fall-back 메시징인데, Circuit breaker에서 Service B가 정상적인 응답을 할 수 없을 때, Circuit breaker가 룰에 따라서 다른 메세지를 리턴하게 하는 방법이다.
예를 들어 Service A가 상품 목록을 화면에 뿌려주는 서비스이고, Service B가 사용자에 대해서 머신러닝을 이용하여 상품을 추천해주는 서비스라고 했을때, Service B가 장애가 나면 상품 추천을 해줄 수 없다.
이때 상품 진열자 (MD)등이 미리 추천 상품 목록을 설정해놓고, Service B가 장애가 난 경우 Circuit breaker에서 이 목록을 리턴해주게 하면 머신러닝 알고리즘 기반의 상품 추천보다는 정확도는 낮아지지만 최소한 시스템이 장애가 나는 것을 방지 할 수 있고 다소 낮은 확률로라도 상품을 추천하여 꾸준하게 구매를 유도할 수 있다.
이 패턴은 넷플릭스에서 자바 라이브러리인 Hystrix로 구현이 되었으며, Spring 프레임웍을 통해서도 손쉽게 적용할 수 있다.
이렇게 소프트웨어 프레임웍 차원에서 적용할 수 있는 방법도 있지만 인프라 차원에서 Circuit breaker를 적용하는 방법도 있는데, envoy.io 라는 프록시 서버를 이용하면 된다.
소프트웨어를 사용하는 경우 관리 포인트가 줄어드는 장점은 있지만, 코드를 수정해야 하는 단점이 있고, 프로그래밍 언어에 따른 종속성이 있다.
반대로 인프라적인 접근의 경우에는 코드 변경은 필요 없으나, Circuit breaker용 프록시를 관리해야하는 추가적인 운영 부담이 늘어나게 된다.
이 글에서는 넷플릭스의 Hystrix, Spring circuit breaker를 이용한 소프트웨어적인 접근 방법과 envoy.io를 이용한 인프라적인 접근 방법 양쪽을 모두 살펴보기로 한다.
넷플릭스 Hystrix
넷플릭스는 MSA를 잘 적용하고 있는 기업이기도 하지만, 적용되어 있는 MSA 디자인 패턴 기술들을 오픈소스화하여 공유하는 것으로도 유명하다. Hystrix는 그중에서 Circuit breaker 패턴을 자바 기반으로 오픈소스화한 라이브러리이다.
Circuit breaker 자체를 구현한것 뿐만 아니라, 각 서비스의 상태를 한눈에 알아볼 수 있도록 대쉬보드를 같이 제공한다.
Hystrix 라이브러리 사용방법
Hystrix를 사용하기 위해서는 pom.xml에 다음과 같이 라이브러리 의존성을 추가해야 한다.
<dependency>
<groupId>com.netflix.hystrix</groupId>
<artifactId>hystrix-core</artifactId>
<version>1.5.4</version>
</dependency>
<dependency>
<groupId>com.netflix.rxjava</groupId>
<artifactId>rxjava-core</artifactId>
<version>0.20.7</version>
</dependency>
Circuit breaker는 Hystrix 내에서 Command 디자인 패턴으로 구현된다. 먼저 아래 그림과 같이 HystrixCommand 클래스를 상속받은 Command 클래스를 정의한 후에, run() 메서드를 오버라이드하여, run 안에 실제 명령어를 넣으면 된다. HystrixCommand 클래스를 상속받을때 runI()메서드에서 리턴값으로 사용할 데이타 타입을 <>에 정의한다.
public class CommandHelloWorld extends HystrixCommand<String>{
private String name;
CommandHelloWorld(String name){
super(HystrixCommandGroupKey.Factory.asKey("ExampleGroup"));
this.name = name;
}
@Override
protected String run() {
return "Hello" + name +"!";
}
이렇게 Command가 정의되었으면 호출 방법은 아래와 같다.
CommandHelloWorld helloWorldCommand = new CommandHelloWorld("World");
assertEquals("Hello World", helloWorldCommand.execute());
먼저 Command 클래스의 객체를 생성한 다음에, 객체.execute()를 이용해서 해당 command 를 실행하면 된다. 이렇게 하면, Command 클래스가 응답을 제대로 받지 못할때는 Circuit Breaker를 이용하여 연결을 강제적으로 끊고 에러 메세지등을 리턴하도록 된다.
전체 코드 샘플은 https://github.com/bwcho75/msa_pattern_sample/tree/master/hystrix 를 참고하기 바란다.
웹서비스에 적용하는 방법
대략적인 개념을 이해하였으면 실제로 이 패턴을 REST API로 구성된 MSA 기반의 서비스에 적용해보자.
두 개의 서비스 User와 Item이 있다고 가정하자 User 서비스가 REST API 호출을 이용하여 Item 서비스를 호출하는 구조라고 할때 이 User → Item 서비스로의 호출을 HystrixCommand를 이용하여 Circuit breaker로 구현해보도록 하자.
User 서비스의 전체 코드는 https://github.com/bwcho75/msa_pattern_sample/tree/master/UserService , Item 서비스의 전체코드는 https://github.com/bwcho75/msa_pattern_sample/tree/master/ItemService 에 있다.
각 코드는 Spring Web을 이용하여 구현되었으며 User → Item으로의 호출을 resttemplate을 이용하였다.
User → Item 서비스를 호출하여 해당 사용자에 속한 Item 목록을 읽어오는 Command를 GetCommand라고 하자, 코드는 대략 아래와 같다.
public class GetItemCommand extends HystrixCommand<List<User>>{
String name;
public GetItemCommand(String name) {
super(HystrixCommandGroupKey.Factory.asKey("ItemServiceGroup"));
this.name = name;
}
@Override
protected List<User> run() throws Exception {
List<User> usersList = new ArrayList<User>();
// call REST API
(생략)
return usersList;
}
@Override
protected List<User> getFallback(){
List<User> usersList = new ArrayList<User>();
usersList.add(new User(name,"myemail@mygoogle.com"));
return usersList;
}
}
리턴 값이 List<User>이기 때문에, HystrixCommand <List<User>>를 상속하여 구현하였고, Item 서비스를 호출하는 부분은 run() 메서드에 구현한다. (restTemplate을 이용하여 호출하는 내용은 생략하였다.)
여기서 주목해야할 부분은 getFallBack() 함수인데, 호출되는 서비스 Item이 장애 일때는 이를 인지하고 getFallBack의 리턴값을 fallback 메세지로 호출한다.
Item과 User 서비스를 각각 실행한다.
%java -jar ./target/User-0.0.1-SNAPSHOT.jar
%java -jar ./target/Item-0.0.1-SNAPSHOT.jar
두 서비스를 실행 한후에 아래와 같이 User 서비스를 호출하면 다음과 같이 ItemList가 채워져서 정상적으로 리턴되는 것을 볼 수 있다.
terrycho-macbookpro:~ terrycho$ curl localhost:8081/users/terry
[{"name":"terry","email":"myemail@mygoogle.com","itemList":[{"name":"computer","qtetertertertertetttt
Item 서비스 서버를 인위적으로 죽인 상태에서 호출을 하면 다음과 같이 위에서 정의한 fall back 메세지와 같이 email이 “myemail@mygoogle.com”으로 호출되고 itemList는 비어 있는채로 리턴이 된다.
terrycho-macbookpro:~ terrycho$ curl localhost:8081/users/terry
[{"name":"terry","email":"myemail@mygoogle.com","itemList":[]}]
지금까지 간단하게나마 Circuit breaker 패턴과 넷플릭스의 Hystrix 오픈소스를 이용하여 Circuit breaker를 구현하는 방법에 대해서 알아보았다.
서비스 상태에 따라서 Circuit을 차단하는 방법등도 다양하고, Command 패턴을 처리하는 방법 (멀티 쓰레드, 세마포어 방식)등이 다양하기 때문에, 자세한 내부 동작 방법 및 구현 가이드는 https://github.com/Netflix/Hystrix/wiki/How-it-Works 를 참고하기 바란다.
Circuit breaker 패턴은 개인적인 생각에서는 MSA에서는 거의 필수적으로 적용해야 하는 패턴이라고 생각을 하지만 Hystrix를 이용하면 Command를 일일이 작성해야 하고, 이로 인해서 코드 복잡도가 올라갈 수 있다. 이를 간소화 하기 위해서 Spring 오픈소스에 이 Hystrix를 잘 추상화 해놓은 기능이 있는데, 그 부분 구현에 대해서는 다음글을 통해서 살펴보도록 한다.
Circuit breaker 패턴을 이용한 장애에 강한 MSA 서비스 구현하기 #2
Spring을 이용한 Circuit breaker 구현
앞의 글에서는 넷플릭스 Hystrix를 이용하여 Circuit break를 구현해보았다.
실제 개발에서 Hystix로 개발도 가능하지만, 보통 자바의 경우에는 Spring framework을 많이 사용하기 때문에 이번 글에서는 Spring framework을 이용한 Circuit breaker를 구현하는 방법을 알아보도록 한다.
다행이도 근래에 Spring은 넷플릭스의 MSA 패턴들을 구현화한 오픈 소스들을 Spring 오픈 소스 프레임웍안으로 활발하게 합치는 작업을 진행하고 있어서 어렵지 않게 구현이 가능하다.
구현하고자 하는 시나리오는 앞의 글에서 예제로 사용한 User service에서 Item Service를 호출하는 구조를 구현하고, User service에 circuit breaker를 붙여보도록 하겠다.
User service 코드 전체는 https://github.com/bwcho75/msa_pattern_sample/tree/master/user-spring-hystrix 에 그리고 Item Service 코드 전체는 https://github.com/bwcho75/msa_pattern_sample/tree/master/item-spring-hystrix 에 있다
Spring Circuit breaker 구현
User service pom.xml 정의
Hystrix circuit breaker를 사용하기 위해서는 pom.xml에 다음과 같이 hystrix 관련 라이브러리에 대한 의존성을 정의해줘야 한다.
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
<version>1.4.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix-dashboard</artifactId>
<version>1.4.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
<version>1.5.11.RELEASE</version>
</dependency>
spring-cloud-starter-hystrix 는 Hystrix circuit breaker를 이용한 의존성이고 hystrix-dashboard와 actuator 는 hystix dash 보드를 띄우기 위한 의존성이다.
User service 구현
UserApplication
Circuit breaker를 이용하기 위해서는 User Service의 메인 함수인 UserApplication 에 Annotation으로 선언을 해준다.
package com.terry.circuitbreak.User; | |
import org.springframework.boot.SpringApplication; | |
import org.springframework.boot.autoconfigure.SpringBootApplication; | |
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker; | |
import org.springframework.cloud.netflix.hystrix.dashboard.EnableHystrixDashboard; | |
@SpringBootApplication | |
@EnableCircuitBreaker | |
@EnableHystrixDashboard | |
public class UserApplication { | |
public static void main(String[] args) { | |
SpringApplication.run(UserApplication.class, args); | |
} | |
} |
위의 코드와 같이 @EnableCircuitBreaker Annotation을 추가해주면 Circuit breaker를 사용할 수 있고, 그리고 추가적으로 Hystrix 대쉬 보드를 사용할것이기 때문에, @EnableHystrixDashboard Annotation을 추가한다.
Item Service를 호출
그러면 UserSerivce에서 ItemService를 호출하는 부분을 구현해보도록 하자. Hystrix와 마찬가지로 Spring Hystrix에서도 타 서비스 호출은 Command로 구현한다. 아래는 Item Service에서 Item 목록을 가지고 오는 GetItemCommand 코드이다.
GetItemCommand
Hystrix Command와 거의 유사하지만 Command를 상속 받아서 사용하지 않고, Circuit breaker를 적용한 메서드에 간단하게 @HystrixCommand Annotation만을 추가하면 된다.
아래 코드를 자세하게 보자. 주의할점은 Item Service 호출을 RestTemplate API를 통해서하는데, RestTemplate 객체인 resetTemplate는 Autowrire로 생성한다.
@Service | |
public class GetItemCommand { | |
@Autowired | |
RestTemplate restTemplate; | |
@Bean | |
public RestTemplate restTemplate() { | |
return new RestTemplate(); | |
} | |
// GetItem command | |
@HystrixCommand(fallbackMethod = "getFallback") | |
public List<User> getItem(String name) { | |
List<User> usersList = new ArrayList<User>(); | |
List<Item> itemList = (List<Item>)restTemplate.exchange("http://localhost:8082/users/"+name+"/items" | |
,HttpMethod.GET,null | |
,new ParameterizedTypeReference<List<Item>>() {}).getBody(); | |
usersList.add(new User(name,"myemail@mygoogle.com",itemList)); | |
return usersList; | |
} | |
// fall back method | |
// it returns default result | |
@SuppressWarnings("unused") | |
public List<User> getFallback(String name){ | |
List<User> usersList = new ArrayList<User>(); | |
usersList.add(new User(name,"myemail@mygoogle.com")); | |
return usersList; | |
} | |
} |
Item Service를 호출하는 코드는 getItem(String name) 메서드이다. 여기에 Circuit breaker를 적용하기 때문에, 메서드 앞에 @HystrixCommand(fallbackMethod = "getFallback") Annotation을 정의하였다. 그리고 Item Service 장애시 호출한 fallback 메서드는 getFallback 메서드로 지정하였다.
getItem안에서는 ItemService를 RestTemplate을 이용하여 호출하고 그 결과를 List<User> 타입으로 반환한다.
앞서 정의한 Fallback은 getFallback() 메서드로 Circuit breaker를 적용한 원래 함수와 입력 (String name)과 출력 (List<User>) 인자가 동일하다.
Circuit breaker 테스트
User service와 Item Service를 기동한 상태에서 user service를 호출하면 아래와 같이 itemList에 Item Service가 리턴한 내용이 같이 반환 되는 것을 확인할 수 있다.
terrycho-macbookpro:~ terrycho$ curl localhost:8081/users/terry
[
{
"name":"terry",
"email":"myemail@mygoogle.com",
"itemList":[
{
"name":"computer",
"quantity":1
},
{
"name":"mouse",
"quantity":2
}
]
}
]
Item Service를 내려놓고 테스트를 해보면 지연 응답 없이 User service로 부터 응답이 리턴되고, 앞서 정의한 fallback 메서드에 의해서 itemList에 아무 값이 없인할 수 있다.
terrycho-macbookpro:~ terrycho$ curl localhost:8081/users/terry
[
{
"name":"terry",
"email":"myemail@mygoogle.com",
"itemList":[]
}
]
Hystrix Dashboard
User service에서 Hystrix Dash board를 사용하도록 설정하였기 때문에, User Service의 호출 상태를 실시간으로 확인할 수 있다.
User serivce 서버의 URL인 localhost:8081에서 localhost:8081/hystrix.stream을 호출 해보면
아래와 같이 Circuit Breaker가 적용된 메서드의 상태 현황 정보가 계속해서 업데이트 되면서 출력하는 것을 확인할 수 있다.
그러면 대쉬보드에 접속해보자 대쉬 보드 URL은 http://{user service}/hystrix 이다. User service url이 localhost:8081이기 때문에 http://localhost:8081/hystrix로 접속해보자
대쉬 보드에서는 모니터링 할 서비스의 스트림 URL을 넣어줘야 하는데 위에서 설명한 http://localhost:8081/hystrix.stream 을 입력한다.
URL을 입력하고 모니터링을 하면 아래와 같이 Circuit breaker가 등록된 서비스들이 모니터링 된다.
아래 그림은 부하가 없을때 상태이다.
실제로 부하를 주게 되면 아래와 같이 그래프가 커져가면서 정상적인 호출이 늘어가는 것을 확인할 수 있고, 응답 시간들도 모니터링이 가능하다.
아래는 Circuit breaker를 통해서 호출되는 Item service를 죽였을때인데, 그래프가 붉은색으로 표시되면서 붉은색 숫자가 증가하는 것을 볼 수 있고 Item service가 장애이기 때문에, Circuit 의 상태가 Close에서 Open을 변경된것을 확인할 수 있다.
운영 적용에 앞서서 고려할점
앞에서 예제로 사용한 Dashboard는 어디까지나 테스트 수준에서 사용할만한 수준이지 실제 운영환경에 적용할때는 여러가지 고려가 필요하다. 특히 /hystrix , /hystrix.stream이 외부에서 접근이 가능하기 때문에,, 이에 대해서 이 두 URL이 외부로 접근하는 것을 막아야 하며, circuit의 상태에 대한 정보를 하나의 서비스만 아니라 여러 서비스에서 대용량 서비스에 적용할시에는 중앙 집중화된 대쉬보드가 필요하고 또한 많은 로그를 동시에 수집해야 하기 때문에, 대용량 백앤드가 필요하다. 이를 지원하기 위해서 넷플릭스에서는 터빈 (Turbine)이라는 이름으로, 중앙 집중화된 Hystrix 대쉬 보드 툴을 지원하고 있다. (https://github.com/Netflix/turbine/wiki)
이번 글에서는 Spring 프레임웍을 이용하여 Circuit breaker 패턴을 Hystrix 프레임웍을 이용하여 적용하는 방법을 알아보았다.
Spring을 사용하면 편리는 하지만 자바 스택만을 지원한다는 한계점을 가지고 있다. Circuit breaker를 이처럼 소프트웨어로 지원할 수 도 있지만, 소프트웨어가 아닌 인프라 설정을 이용해서 적용이 가능한데, envoryproxy 를 이용하면 코드 변경 없이 모든 플랫폼에 적용이 가능하다. 다음 글에서는 envoy proxy를 이용하여, circuit breaker를 사용하는 방법에 대해서 알아보도록 한다.