패턴:회로 차단기
컨텍스트
마이크로 서비스 아키텍처를 적용했습니다.서비스는 요청을 처리 할 때 공동 작업을하는 경우가 있습니다.한 서비스가 동 기적으로 다른 서비스를 호출 할 때 항상 다른 서비스를 사용할 수 없거나 본질적으로 사용할 수없는 높은 대기 시간을 나타낼 가능성이 있습니다.스레드와 같은 귀중한 리소스는 다른 서비스가 응답할 때까지 기다리는 동안 호출자에서 소비될 수 있습니다.이로 인해 리소스가 고갈되어 호출 서비스가 다른 요청을 처리할 수 없게 될 수 있습니다.한 서비스의 실패는 잠재적으로 응용 프로그램 전체에서 다른 서비스로 캐스케이드될 수 있습니다.
문제
네트워크 또는 서비스 오류가 다른 서비스로 계단식되는 것을 방지하는 방법은 무엇입니까?
솔루션
서비스 클라이언트는 전기 회로 차단기와 유사한 방식으로 작동하는 프록시를 통해 원격 서비스를 호출해야 합니다.연속 실패 수가 임계값을 초과하면 회로 차단기가 트립되고 시간 초과 기간 동안 원격 서비스를 호출하려는 모든 시도가 즉시 실패합니다.제한 시간이 만료되면 회로 차단기는 제한된 수의 테스트 요청을 통과 할 수 있습니다.이러한 요청이 성공하면 회로 차단기가 정상 작동을 재개합니다.그렇지 않으면 오류가 발생하면 시간 초과 기간이 다시 시작됩니다.
예제
RegistrationServiceProxy
마이크로 서비스 예제 응용 프로그램에서 원격 서비스를 호출할 때 오류를 처리하기 위해 회로 차단기를 사용하는 스칼라로 작성된 구성 요소의 예입니다.
@Componentclass RegistrationServiceProxy @Autowired()(restTemplate: RestTemplate) extends RegistrationService { @Value("${user_registration_url}") var userRegistrationUrl: String = _ @HystrixCommand(commandProperties=Array(new HystrixProperty(name="execution.isolation.thread.timeoutInMilliseconds", value="800"))) override def registerUser(emailAddress: String, password: String): Either = { try { val response = restTemplate.postForEntity(userRegistrationUrl, RegistrationBackendRequest(emailAddress, password), classOf) response.getStatusCode match { case HttpStatus.OK => Right(response.getBody.id) } } catch { case e: HttpClientErrorException if e.getStatusCode == HttpStatus.CONFLICT => Left(DuplicateRegistrationError) } }}
@HystrixCommand
는 회로 차단기를 사용하여 실행할registerUser()
에 대한 호출을 정렬합니다.
회로 차단기 기능은UserRegistrationConfiguration
클래스의@EnableCircuitBreaker
주석을 사용하여 활성화됩니다.
@EnableCircuitBreakerclass UserRegistrationConfiguration {
결과 컨텍스트
이 패턴에는 다음과 같은 이점이 있습니다:
- 서비스가 호출하는 서비스의 오류를 처리합니다
이 패턴에는 다음과 같은 문제가 있습니다:
- 오 탐지를 만들거나 과도한 대기 시간을 발생시키지 않고 시간 초과 값을 선택하는 것은 어렵습니다.
- 서버 측 검색 라우터는 이 패턴을 사용하여 서비스를 호출할 수 있습니다.