본문 바로가기

Java/Pattern

[Java][Circuit breaker] Hystrix 이해와 사용 방법

반응형

서론

MSA 기반을 둔 Application은 클라이언트 회복성이 고려되어야하고,

핵심적인 클라이언트 회복성 패턴은 주로 회로 차단(Circuit breaker), 폴백(fall back), 벌크 헤드(bulk head) 이다.

 

Circuit breaker Pattern은 느리게 실행되고, 성능이 저하된 시스템 호출을 종료해 빨리 실패시키고 자원 고갈을 방지한다.

Fall back Pattern은 개발자가 원격 서비스 호출이 실패하거나 호출에 대한 회로 차단기가 실패할때 대체할 코드 경로를 정의할 수있다.

Bulk head Pattern은 원격 호출을 서로 격리하고 원격 서비스 호출을 자체 스레드 풀로 분리한다.

 

즉, 일련의 서비스 호출이 실패할 때 Application container의 모든 자원이 고갈되어서는 안된다.

본론

Histrix은 Netflix에서 Circuit breaker, Fall back, Bulk head Pattern을 구현한 라이브러리이다.

현재 MSA를 지향하고 있는데, MSA(Micro Service Architecture)에서 쓰는 장애 전파 방지 전략 중 하나라고 이해하면 된다.

 Histrix 이해 

기본적으로 Histrix는 부모 thread의 context를 Histrix 명령이 관리하는 thread에 전파하지 않는다.

https://github.com/Netflix/Hystrix/wiki/How-it-Works

실행순서 내용
1

* circuit health check을 위한 최소 요청(HystrixCommandProperties.circuitBreakerRequestVolumeThreshold())이 있는 경우
* 지정한 오류율(HystrixCommandProperties.circuitBreakerErrorThresholdPercentage())을 초과한 경우

2 회로의 상태를 CLOSED에서 OPEN으로 변경
3 회로가 열린 동안, 모든 요청에 대해서 fallback method을 바로 실행
4 일정 시간(HystrixCommandProperties.circuitBreakerSleepWindowInMilliseconds())이 지난 후
하나의 요청을 원래 method로 실행(HALF OPEN)

5 이 요청이 실패하면 OPEN로 상태 변경  1번부터 실행 이 요청이 성공하면 CLOSED로 상태 변경 ⇢ 3번부터 실행

 

이때, Hystrix은 @HystrixCommand 개체로 보호되는 것을 뜻하며 THREAD 격리 수준을 사용하고 있다고 가정한다.

 

참고로 Histrix는 THREAD와 SEMAPHORE 격리 모델을 지원한다.

SEMAPORE 모델은 Histrix 호출을 위해 별도의 스레드를 사용하지 않고,
이 호출을 중단할때 서비스가 예상하지 않는 동작도 유발할 수 있다.

Histrix를 사용하면 사용자가 정의한 HystrixConcurrencyStrategy를 구현해

부모 Thread Context를 Histrix가 관리하는 Thread에 주입할 수 있다.

 Histrix 사용 방법 

예를 들어, REST 기반 환경에서 종종 서비스를 운영하는데 Context 관련 정보를 서비스 호출로 전달하려고 한다.

이때 REST/HTTP 헤더에 상관관계 ID나 모든 하위 서비스 호출에 전파 할 수 있다.

그러면 상관관계 ID를 사용하면 한 트랜잭션 내 여러 서비스 호출을 추적할 수 있는 고유한 식별자(ID)를 갖게 된다.

 

이 값을 모든 서비스 호출에 사용하게 하려면 스프링 필터(Spring Filter) 클래스를 사용해 REST 서비스에 대한 모든 호출을 가로채고,

유입되는 HTTP 요청에서 Context 정보를 추출해 사용자가 정의한 Context 객체에 저장할 수 있다.

 

(1)  HystrixCommandHandler.java : HystrixEventNotifier를 통해 Hystrix Event에 대해 알림 받을 수 있음
(★ Hystrix Event 은 하단 [참고] 내용에 좀 더 상세히 표기했음)

import com.netflix.hystrix.HystrixCommandKey;
import com.netflix.hystrix.HystrixEventType;
import com.netflix.hystrix.strategy.eventnotifier.HystrixEventNotifier;

public class HystrixCommandHandler extends HystrixEventNotifier {
    @Override
    public void markEvent(HystrixEventType eventType, HystrixCommandKey commandKey) {
        System.out.printf("-->Event, type=%s, Key=%s%n", eventType, commandKey);

        if (eventType.equals(HystrixEventType.FALLBACK_SUCCESS)) {
            this.sendFailMessage(eventType);
        }
    }
…
}

 

(2) Service.java : @HystrixCommand를 통해  Circuit breaker, Fall back 구현

@Service
public class Service {
  @HystrixCommand(fallbackMethod = "fallBackDoSomething")
  public void doSomething() {
      System.out.println("Test Logic");
  }

  public void fallBackDoSomething(Throwable throwable) {
      System.out.printf("exception=%s%n", throwable);
  }
}

 

(3) Application.java : @EnableCircuitBreaker 를 통해 Application에서 Hystrix를 사용, HystrixPlugins으로 HystrixCommandHandler.java 를 bean 등록

import com.netflix.hystrix.strategy.HystrixPlugins;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.context.ConfigurableApplicationContext;

@SpringBootApplication
@EnableCircuitBreaker
public class Application {
  public static void main(String[] args) {
        HystrixPlugins.getInstance().registerEventNotifier(new HystrixCommandHandler());
        SpringApplication.run(Application.class, args);
    }
}

 


[ 참고 ]

HystrixEventType

Type

설명

내용

SUCCESS

성공

HTTP 200

FAILURE

오류

Request 실패

FALLBACK_SUCCESS

FallBack 성공

설정한 Hystrix(@HystrixCommand) 의해 FallBack 함수 실행 성공

FALLBACK_FAILURE

FallBack 실패

설정한 Hystrix(@HystrixCommand) 의해 FallBack 함수 실행 실패

EXCEPTION_THROWN

Exception 처리

Fall back 함수 실행 실패로 Exception 처리

SHORT_CIRCUITED

CircuitBreaker 실행

Fall back 함수가 실행되며 CircuitBreaker 실행

Fall back 성공되어야 실행됨

HTTP 200으로 들어와도 Fall back 함수 실행됨

 

 


[관련 서적] books.google.co.kr/books?id=VACDDwAAQBAJ

 

스프링 마이크로서비스 코딩 공작소

제네시스(Genesys)의 수석 클라우드 엔지니어로 PureCloud 부서에서 근무 중이다. AWS 플랫폼에서 전화 통신 기반 마이크로서비스를 구축하면서 시간을 보낸다. 자바, Clojure, Go를 포함한 여러 기술 플

books.google.co.kr

[관련 내용] github.com/Netflix/Hystrix

 

Netflix/Hystrix

Hystrix is a latency and fault tolerance library designed to isolate points of access to remote systems, services and 3rd party libraries, stop cascading failure and enable resilience in complex di...

github.com

[Histrix 상세 설정] github.com/Netflix/Hystrix/wiki/configuration#command-properties

 

Netflix/Hystrix

Hystrix is a latency and fault tolerance library designed to isolate points of access to remote systems, services and 3rd party libraries, stop cascading failure and enable resilience in complex di...

github.com

 

반응형

❥ CHATI Github