스프링 레트리는 스프링 배치와 독립적 인 에너지 기능으로, 주로 재 시도와 퓨즈를 구현합니다. 재 시도에 대한 시나리오 제한이 있으며, 모든 시나리오가 불법 매개 변수 검증, 쓰기 작업 등과 같은 재 시도에 적합한 것은 아닙니다 (쓰기가 edempotent인지 여부를 고려해야 함)는 재 시도에 적합하지 않습니다. 원격 통화 시간 초과 또는 네트워크 중단을 재 시도 할 수 있습니다. 마이크로 서비스 거버넌스 프레임 워크에서 일반적으로 자체 재시도 및 시간 초과 구성이 있습니다. 예를 들어, Dubbo는 Retries = 1, TimeOut = 500 호출이 실패하고 한 번만 다시 시도 할 수 있으며 500ms 이상 후에 반환되지 않으면 호출이 실패합니다. 스프링 레트리에서는 재 시도 해야하는 예외 유형을 지정하고 각 재시도에 대한 간격을 설정하고 재시도가 실패한 경우 다시 재시도 또는 퓨즈 (재 시도 중지)를 설정할 수 있습니다.
설계 및 구현
RetryOperations 재 시도 API를 정의합니다. RetryTemplate 은 API의 템플릿 모드 구현으로 재 시도 및 회로 파괴를 구현합니다. 제공된 API는 다음과 같습니다.
공개 인터페이스 리트너로 {<t, e 확장 trashable> t execute (retrycallback <t, e> retrycallback) wrows e; } // 다른 API가 생략되었습니다 RetryCallback 수행 해야하는 작업을 정의합니다. 작업을 정의한 후 재 시도하는 방법에 대한 문제입니다. RetryTemplate 다른 재 시도 전략을 공식화하여 재 시도 방법의 논리를 실행합니다. 기본 재시도 전략은 SimpleRetryPlicy 이므로 3 번 재 시도됩니다. 재 시도가 성공하면 다시 시도하지 않을 것입니다. 그렇다면 3 피트의 재 시도가 실패하면 어떻게됩니까? 프로세스가 끝나거나 상향식 결과를 반환합니다. 상향식 결과를 반환하려면 RecoveyCallBack 구성해야합니다. 이름에서, 당신은 이것이 상향식 콜백 인터페이스라는 것을 알 수 있습니다. SimpleRetryPolicy 외에도 다른 재 시도 전략이 있습니다. RetryPolicy 인터페이스를 살펴 보겠습니다.
공개 인터페이스 retrypolicy는 직렬화 가능한 {boolean canretry (retrycontext context)를 확장합니다. RetryContext Open (RetryContext Parent); void close (retryContext 컨텍스트); void registerThrowable (retryContext 컨텍스트, 던질 수있는 던지기 가능);} canRetry 다시 시도 할 때마다 호출됩니다. 다시 시도 할 수 있는지 여부의 판단 조건
open 재시도가 시작되기 전에 호출되면 레트리 컨텍스트가 RetryContext 에 생성되며 레트리 스택이 저장됩니다.
registerThrowable 예외가 다시 시도 될 때마다 호출됩니다 (예외가 있으며 계속 재 시도합니다).
예를 들어 SimpleRetryPolicy 가져 가십시오. 재 시도 횟수가 3 (기본값 3 회)에 도달하면 재 시도를 중지하면 재 시도 컨텍스트에서 재 시도 횟수가 저장됩니다.
다음과 같은 재 시정 전략 구현을 제공하십시오.
재 시도 폴백 전략은 각 재 시도가 즉시 재 시도되는지 또는 다시 시도하기 전에 잠시 기다리는지를 나타냅니다. 기본적으로 대기 기간을 구성 해야하는 경우 백 오프 정책 BackoffRetryPolicy 지정한 다음 다시 시도해야합니다. BackOffRetryPolicy에는 다음과 같은 구현이 있습니다.
상태의 재 시도 또는 무국적 재 시도
소위 무국적 재 시도는 스레드 컨텍스트에서 완료된 재 시도를 말합니다. 그렇지 않으면 실 컨텍스트에서 완료되지 않은 경우 상태가 정한 재 시도입니다. 이전의 SimpleRetryPolicy 레트리가 루프에서 완료 되었기 때문에 무국적 재 시도였습니다. 그렇다면 그 후에는 어떻게되거나 국가에서 다시 시도해야합니까? 일반적으로 트랜잭션 롤백 및 회로 차단기의 두 가지 상황이 있습니다.
DataAccessException은 예외적입니다. 재 시도는 수행 할 수 없지만 다른 예외가 발생하면 다시 시도 할 수 있습니다.
퓨즈는 현재 루프에서 재 시도가 아니라 글로벌 재 시도 모드 (스레드 컨텍스트가 아님)를 처리하는 것을 의미합니다. 회로 차단기는 루프에서 벗어나고 스레드 컨텍스트의 스택 정보가 필연적으로 손실됩니다. 그런 다음이 정보를 "글로벌 모드"로 저장해야합니다. 현재 구현은 캐시 (맵 구현)에 배치됩니다. 다음에 캐시에서 얻은 후에 다시 시도 할 수 있습니다.
빠른 시작
Retry를 수행 해야하는 클래스에서 @EnableRetry 사용하십시오. proxyTargetClass=true 가 설정되면 cglib dynamic proxy를 사용합니다.
@configuration@enabreticretry (proxyTargetClass = true) @componentpublic class retryexamples {} 재 시도 최대 재시도 전략에 따라 재 시도 전략에 따라 재 시도가 3 번 반복되고 예외가 여전히 발생하면 재 시도가 중지되고 상향식 콜백이 실행됩니다. 따라서 최종 출력 결과는 Integer.MAX_VALUE 입니다.
개인 void retryexample3 ()는 예외를 던졌습니다. {retrytemplate retrytemplate = new retrytemplate (); simpleretrypolicy simpleretrypolicy = new SimpleretryPolicy (); simpleretrypolicy.setmaxattempts (3); retrytemplate.setretrypolicy (simpleretrypolicy); 정수 결과 = retrytemplate.execute (새로운 retrycallback <integer, exception> () {int i = 0; // 작업을 재 시도 @override public integer dowithretry (retrycontext retrycontext) 예외 {log.info ( "retry count : {}", retrycontreptrycount (retrycontrept.get); }, 새로운 recoverCallback <integer> () {// restry @override public regger recge (retrycontext retrycontext)는 {retry : {}, 복구 메소드! ", retryContext.getRetryCount (); log.info ( "최종 결과 : {}", 결과); } private int len (int i)은 예외를 던져 {if (i <10) 새로운 예외를 던지기 (i + "le 10"); 반환 i; }다음은 회로 차단기 레트리 정책 모드 (회로 브레이크 레트 트리 폴리) 사용 방법에 대해 설명합니다. 다음 세 매개 변수를 설정해야합니다.
회로 차단기 개방 및 폐쇄 판단 :
테스트 코드는 다음과 같습니다.
retrytemplate template = 새로운 리트리 테템 플레이트 (); CircuitBreakErretryPolicy retrypolicy = 새로운 회로 브레이크 브레이크 레트 트리 폴리 (new CircuitbreakErretypolicypolicy) (New SimpleretryPolicy (3)); retrypolicy.setopentimeout (5000); retrypolicy.setResettimeout (20000); template.setretrypolicy (retrypolicy); for (int i = 0; i <10; i ++) {//thread.sleep(100); {object key = "회로"를 시도하십시오. 부울 isforcerefresh = false; Retrystate State = 새로운 Defaultretretrystate (key, isforcerefresh); String result = template.execute (새로운 retrycallback <string, runtimeexception> () {@override public string dowithRetry (retryContext Context)는 runtimeexception {log. @override public string regever (retryContext Context) 예외 {return "default"); log.info ( "결과 : {}", 결과); } catch (예외 e) {System.out.println (e); }} isForceRefresh = false 설정되므로 key = "circuit" (즉, retryContext)의 값이 캐시에서 얻어집니다. 따라서 재 시도가 실패하고 this.time < this.openWindow 융합되면 글로벌 모드에서 계속 재 시도를 계속 구현할 수 있습니다 (획득 한 RetryContext 동일합니다).
주석 개발
레트리 요구 사항이있을 때마다 레트 RetryTemplate 작성하는 경우 너무 부풀어 오르면 주석을 사용하면 개발을 크게 단순화하고 중복 코드를 줄일 수 있습니다. 다음은 주석을 사용하여 구현 된 최대 재시도 전략의 재시입니다.
@retryable (value = sqldataexception.class, backoff = @backoff (value = 0l)) public string service3 () 던지기 sqldataexception {log.info ( "service3 open"); 새로운 sqldataexception () 던지기; } @Recover public string regever (sqldataexception ne) {return "sqldataexception 복구"; }주석은 다음과 같습니다.
@enabreretry
@retryable
@다시 덮다
@backoff
@CircuitBreaker
@enabreretry : 다시 시도해 볼 수 있습니까? proxytargetClass 속성이 true (기본 거짓) 인 경우 cglib 프록시를 사용하십시오.
@retryable : 주석을 다시 시도 해야하는 방법
@backoff : 폴백 전략을 다시 시도하십시오 (지금 시도하거나 다시 시도하기 전에 잠시 기다리십시오)
@recover : 메소드와 함께 사용합니다. @retryable이 실패 할 때 "보장 된"방법으로 사용됩니다. @recover 주석의 방법은 @retryable 주석의 "서명"방법과 일치해야합니다. 첫 번째 항목 매개 변수는 재 시도 할 예외입니다. 다른 매개 변수는 @retryable과 일치합니다. 반환 값은 동일해야합니다. 그렇지 않으면 실행할 수 없습니다!
@CircuitBreaker : 메소드에 사용되며 회로 브레이킹 모드를 구현하십시오.
더 많은 예를 보려면 내 github (https://github.com/happyxiaofan/springboot-learning-example)에 오신 것을 환영합니다. 감사해요
위는이 기사의 모든 내용입니다. 모든 사람의 학습에 도움이되기를 바랍니다. 모든 사람이 wulin.com을 더 지원하기를 바랍니다.