탄력성 마이크로 서비스를 구축하십시오 : 회로 차단기, 회수

탄력성 마이크로 서비스를 구축하십시오 : 회로 차단기, 회수

무슨 일이야, 동료 괴짜? 바쁜 피자 장소에서 치료를받는 시간을 생각해보십시오. 피자 오븐이 고장 났고 새로운 주문이 들어 오면서 주방 전체가 정지되었습니다. 우리가 그 오븐을 벗겨지고 신뢰할 수없는 타사 API로 가져 가면, 당신은 그곳으로 간다-미세 서비스 재난! 리트리 및 회로 차단기를 사용하여 처분하면 시스템이 충돌하는 대신 지글 지글을 유지할 수 있습니다.

이 안내서에서는 화이트 보드에서 쌍 프로그래밍을하고 있다고 가정 할 때 이러한 패턴을 공유 할 것입니다. 우리는 일부 코드 (Hystrix 및 Resilience4J)를보고, 전쟁 이야기를 전쟁하고, 실패에 대한 이야기 ​​(힌트 : 야생 재림), 즐거운 시간을 보낼 것입니다. 내려 가자, 우리는?

마이크로 서비스에서 탄력성이 선택적이 될 수없는 이유

마이크로 서비스를 릴레이 레이스로 생각하십시오. 두 번째로 싱글 러너가 배턴을 떨어 뜨리고 팀 전체가 레이스에서 패배합니다. 회복력이 없으면 하나의 학대 API 호출이 쉽게 다음과 같이 이어질 수 있습니다.

회로 차단기 및 회수로 진행하십시오.

여기에 단순화가 있습니다. 여기서는 비즈니스 언어가 없습니다.

회로 차단기 패턴 : 시스템 비상 브레이크

작동 방식 : (피자 오븐 비유)

  1. 폐쇄 된 상태 : 모든 것이 작동하고 주문이 흐르고 있습니다.
  2. 개방 상태 : 순서 흐름을 차단하고 비 기능성 난로를보고 있습니다.
  3. 반 개방 상태 : 스토브가 다시 작동하는지 확인하기 위해 스토브를 테스트합니다.

코드의 회로 차단기는 사전 설정 오류 임계 값에서 작동합니다. 진단 될 때까지 기능을 초과하면 기능이 보류됩니다.

코드 예제 : Hystrix – (OG 회로 차단기)

유지 보수 모드로 들어가기 전에 – Netflix의 Hystrix는 라이브러리로 이동했습니다. 이것이 스프링 부트 앱에 포함시키는 방법입니다.

@Service
public class PaymentService {
@HystrixCommand(fallbackMethod = "processPaymentFallback")
public String processPayment(String orderId) {
// Simulate calling a flaky payment gateway
if (Math.random() > 0.5) {
throw new RuntimeException("Payment failed!");
}
return "Payment processed for " + orderId;
}

public String processPaymentFallback(String orderId) {
return "Fallback: Payment queued for " + orderId;
}
}

구성 (application.yml))

hystrix:
command:
default:
circuitBreaker:
requestVolumeThreshold: 5 # Min requests before tripping
errorThresholdPercentage: 50 % failures needed to trip
sleepWindowInMilliseconds: 10000 # Time before half-open

무슨 일이 일어나는지 :

  • 5 번의 실패한 시도 (50%+ 고장) 후 Hystrix에서 회로를 사용합니다.
  • 10 초 동안, 예외없이 모든 통화는 프로세스 결제가 끝나고 모든 통화가 끝나고 모든 통화가 실패합니다.

코드 예 : Resilience4J – 현대 대안

Lightweight Modular 및 Java 8 호환 가능하면 Resilience4J에서 동일한 논리가 구현되는 방법입니다.

CircuitBreakerConfig config = CircuitBreakerConfig.custom()
.failureRateThreshold(50)
.minimumNumberOfCalls(5)
.waitDurationInOpenState(Duration.ofSeconds(10))
.build();

CircuitBreaker circuitBreaker = CircuitBreaker.of("paymentService", config);

public String processPayment(String orderId) {
return circuitBreaker.executeSupplier(() -> {
if (Math.random() > 0.5) {
throw new RuntimeException("Payment failed!");
}
return "Payment processed for " + orderId;
});
}

폴백 추가 :

public String processPayment(String orderId) {
return Decorators.ofSupplier(() -> processPaymentCore(orderId))
.withCircuitBreaker(circuitBreaker)
.withFallback(List.of(RuntimeException.class),
e -> "Fallback: Payment queued for " + orderId)
.get();
}

Hystrix와의 주요 차이점 :

  • 스레드 풀에 의존하지 않습니다 (항상 발신자 스레드를 사용).
  • 더 높은 모듈성 (필요한 것만 사용할 수 있습니다 : 회수, 벌크 헤드 등).

재 시도 패턴 :“세 번의 시도가 필요합니까?”

재 시도시기 (그리고 전화 할 때 종료)

타임 아웃 또는 건너 뛰는 네트워크 (재생산)와 같은 일시적인 실수에 가장 적합합니다. 성공할 수 있습니다.

핵심 원칙 :

  1. 비만적인 운영은 다시 시도해서는 안됩니다 (일부 큰 청구서가 원하지 않는 한 지불과 같은 지불과 같은).

  2. 더 긴 대기 간격은 지수 백 오프 (후속 회수의 대기 시간 증가)에 의해 제안됩니다.

코드 스 니펫 : Resilience4J Retries + 회로 차단기

RetryConfig retryConfig = RetryConfig.custom()
.maxAttempts(3)
.waitDuration(Duration.ofMillis(500))
.retryExceptions(RuntimeException.class)
.build();

Retry retry = Retry.of("paymentRetry", retryConfig);

public String processPayment(String orderId) {
return Decorators.ofSupplier(() -> processPaymentCore(orderId))
.withRetry(retry)
.withCircuitBreaker(circuitBreaker)
.withFallback(...)
.get();
}

흐름:

  1. 최대 3 번의 재시작이 실행되고 (500ms에 의해 간격) 성공하지 못하면 회로 차단기는 최소한 모든 고장을 기억합니다.
  2. 회로가 5 번 열리고 피드백 고장이 기록되면 폴백이 시작됩니다.

자신의 실수를 다루는 것 : 모범 사례

  1. 테스트가 무기한으로 계속되도록 허용하지 말고 시간 초과를 설정하십시오.
TimeLimiterConfig timeoutConfig = TimeLimiterConfig.custom()
.timeoutDuration(Duration.ofSeconds(2))
.build();

2. 모든 것을보아야합니다 : 모든 사람에게 모든 것을 말하십시오. Prometheis와 Grafana를 결합하여 모니터링하십시오.

  • 회로 차단기의 개방 및 폐쇄 된 상태.

  • 시도는 다시 시작됩니다.

  • 오류율에 대한 논의.

3. 테스트 실패 시나리오 : Netflix만이 혼돈 원숭이를위한 유일한 장소는 아닙니다.

전자 상거래의 부분 붕괴 : 사례 연구

Black Friday 라인 동안, 고객은 제품 추천 서비스가 계속 실패함에 따라 주요 문제에 직면하고 있었으며 결과는 느린 제품 페이지였습니다. 다운로드 시간은 엄청난 20 초였습니다.

해결책:

반대로 끝 결과를 명확하게하십시오.

  • 명확한 다운로드 시간은 불과 2 초로 급락했으며 95 %가 크레인 모드로 전환했습니다.
  • 대부분의 사용자는 계정을 입력하고 단서 절대 0이 없습니다.

탄력성 치트 시트

큐: Hystrix 또는 Resilience4J를 선택해야합니까?

에이: Resilience4J, 새로운 프로젝트는 잘 유지되고 Java 8 이상이 필요하기 때문입니다.

큐: 얼마나 많은 재심이 너무 많습니까?

에이: 2 ~ 3 개의 시작 토큰이 효과가 있지만 5 번의 시도 후에도 여전히 아무것도 없다면 문제는 훨씬 더 나쁩니다.

큐: 비동기 호출과 함께 회로 차단기를 사용할 수 있습니까?

에이: 당신은 할 수 있습니다! Resilience4J는 완전성 문제 및 반응기와 통합됩니다.

마무리 : 부러지지 않고 구부리는 시스템

회복력은 시스템이 실패하게하는 동시에 혼란을 피할 수 있습니다. 행동 계획은 다음과 같습니다.

  1. 타사 API 및 데이터베이스와 같이 실패 할 가능성이있는 시도에 대한 회로 차단기를 포함하십시오.
  2. 허용되지 않은 비 혹시 운영을 현명하게 사용하십시오.
  3. Lookout : 회로가 부러진 경우 큰 문제가 있습니다.

API 제안에 실패 할 때 Netflix보다 더 잘하는 사람은 아무도 없습니다. 마법은 그들이 그러한 문제를 정면으로 해결하는 방법에 있습니다.

이제 마이크로 서비스를 강화하지만 댓글 섹션에서 끝없이 루핑되도록 경험을 공유하여 함께 배울 수 있습니다.

출처 참조

Post Comment

당신은 놓쳤을 수도 있습니다