이 기사는 주로 Java 프로그래밍 재 시도 재 시도 메커니즘 예제 및 관련 코드 예제에 대한 자세한 설명을 연구합니다. 편집자는 그것이 꽤 좋다고 생각하고 특정 참조 가치가 있다고 생각합니다. 필요한 친구는 그것을 참조 할 수 있습니다.
응용 프로그램에서 기능을 구현해야합니다. 데이터를 원격 스토리지 서비스에 업로드해야하며 반환 처리가 성공하면 다른 작업이 수행됩니다. 이 기능은 복잡하지 않으며 두 단계로 나뉩니다. 첫 번째 단계는 원격 REST 서비스 로직 래퍼를 호출하여 처리 결과를 처리 방법에 반환하는 것입니다. 두 번째 단계는 첫 번째 단계의 결과를 얻거나 예외를 포착하는 것입니다. 오류 또는 예외가 발생하면 업로드 로직이 다시 시도되면 논리적 작업이 계속됩니다.
일반 업로드 로직을 기반으로, 기능 논리는 반환 결과 또는 예외 결정을 듣는 지 여부를 판단하여 실행됩니다. 동시에, 즉각적인 재 시도의 잘못된 실행을 해결하기 위해 (예외가 외부 실행 불안정성으로 인해 발생한다고 가정 함), 함수 로직은 특정 지연 시간에 대한 재 실행입니다.
public void commonretry (map <string, object> dataMap)는 InterruptedException {map <string, object> parammap = maps.newhashmap (); PARAMMAP.PUT ( "TableName", "CreativeTable"); Parammap.put ( "DS", "20160220"); Parammap.put ( "Datamap", Datamap); 부울 결과 = 거짓; try {result = uploadtoodps (Parammap); if (! result) {thread.sleep (1000); uploadtoodps (Parammap); // 한 번 시도}} catch (예외 e) {Thread.Sleep (1000); uploadtoodps (Parammap); // 한 번 시도}}위의 솔루션은 여전히 재 시도에 대해 유효하지 않을 수 있습니다. 이 문제를 해결하려면 재시도 수와 재시도 간격 간격을 늘려서 재 시도 유효성을 늘릴 가능성을 달성하십시오.
public void commonretry (map <string, object> dataMap)는 InterruptedException {map <string, object> parammap = maps.newhashmap (); PARAMMAP.PUT ( "TableName", "CreativeTable"); Parammap.put ( "DS", "20160220"); Parammap.put ( "Datamap", Datamap); 부울 결과 = 거짓; try {result = uploadtoodps (Parammap); if (! result) {reuploadtoodps (Parammap, 1000L, 10); // 다중 재 시도}} catch (예외 e) {reuploadtoodps (Parammap, 1000L, 10); // 다중 재 시도}}}솔루션 1 및 솔루션 2 : 정상 논리 및 재시도 논리가 강력하게 결합됩니다. 레트리 논리는 정상 논리의 실행 결과에 크게 의존하며, 정상 논리의 예상 결과에 대한 수동적 재 시도 트리거. 재 시도의 근본 원인은 종종 복잡한 논리에 압도되며, 이는 후속 운영 및 유지 보수에 어떤 문제를 해결 해야하는지에 대한 이해가 일관되지 않을 수 있습니다. 재 시도는 보장하기가 어렵고 운영 및 유지 보수에 도움이되지 않습니다. 재 시도 디자인은 정상적인 논리 예외에 의존하거나 추측의 근본 원인을 재 시도하기 때문입니다.
그렇다면 정상 논리와 재 시도 로직을 분리하는 데 사용할 수있는 솔루션이 있으며, 동시에 재 시도 된 솔루션을 표준화 된 솔루션으로 제공 할 수 있습니까? 대답은 다음과 같습니다. 즉, 에이전트 설계 패턴을 기반으로 한 재 시도 도구입니다. 해당 도구를 사용하여 위의 시나리오를 재구성하려고합니다.
명령 설계 패턴의 구체적인 정의는 설명되지 않습니다. 주된 이유는 명령 패턴이 객체를 실행하여 인터페이스 작동 로직을 완료 할 수 있기 때문에 동시에 재 시도 로직의 내부 캡슐화가 구현 세부 사항에 노출되지 않기 때문입니다. 발신자에게는 정상적인 논리의 실행이며 분리의 목표를 달성합니다. 특정 기능 구현을 참조하십시오. (클래스 다이어그램 구조)
Iretry는 업로드 및 재시도 인터페이스에 동의하며, ODPSRETRY와 유사한 ODPS 업로드 로직을 구현하고 재 시도 메커니즘과 재 시도 전략을 동시에 캡슐화합니다. 동시에 복구 방법을 사용하여 끝에 복구 작업을 수행하십시오.
발신자 논리는 재 시도에주의를 기울일 필요가 없습니다. 레트리 레지더를 통해 컨벤션 인터페이스 기능을 구현합니다. 동시에 레트리는 재시 도로에 응답하고 처리해야합니다. 레트리의 특정 레트리 처리는 실제 irtry 인터페이스 구현 클래스 OdpsRetry에 전달됩니다. 명령 모드를 채택함으로써 일반 논리와 재시도 논리는 우아하게 분리되며, 동시에 정상 논리와 재시도 논리는 레트리의 역할을 구축하여 구분되므로 재 시도는 확장 성이 향상됩니다.
Spring-Retry는 오픈 소스 툴킷으로 현재 사용 가능한 버전 1.1.2. Release로 재 시도 작동 템플릿을 사용자 정의하고 재 시도 정책 및 폴백 정책을 설정할 수 있습니다. 동시에 실행 인스턴스를 다시 시도하여 스레드 안전을 보장하십시오. 특정 작업 예제는 다음과 같습니다.
public void 업로드 (최종 맵 <문자열, 개체> 맵) 예외를 던졌습니다 {// 레트리 템플릿 인스턴스 빌드 레트리 테템 플레이트 레트 리트 템플릿 = 새로운 retrytemplate (); // 재 시도 정책을 설정하고 주로 재시도 수를 설정합니다. 단순한 측정 폴리니 정책 = New SimpleretryPolicy (3, 컬렉션. <class <? extends Throwable>, boolean> singletonMap (Exception.Class, true)); // 재 시도 폴백 작동 정책을 설정하고 주로 재 시도 간격을 설정했습니다. FIXEDBACKOFFPOLICY FIXEDBACKOFFPOLICY = 새로운 FIXEDBACKOFFPOLICY (); fixedbackoffpolicy.setbackoffperiod (100); retrytemplate.setretrypolicy (정책); retrytemplate.setbackoffpolicy (fixedbackoffpolicy); // retrycallback 콜백 인스턴스를 재평가하기 위해 정상적인 논리 논리를 래핑하고, 첫 번째 실행 및 재시도 실행은이 논리 최종 RetryCallback <객체, 예외> retryCallback = new retryCallback <객체, 예외> () {// retryContext Retry, Unify Spring-wrappe Public 컨텍스트 (retrycontrows). System.out.println ( "뭔가"); 예외 e = uploadtoodps (map); System.out.println (context.getReTryCount ()); e; //이 시점에 특별한주의를 기울이십시오. 레트리의 근본은 예외를 통해 반환됩니다}}; // 재 시도 프로세스를 검색하면 정상적으로 재 시도 상한에 도달하거나 도달합니다. Final RecoveryCallback <botorcallback = new RecoveryCallback <botal> () {public 객체 복구 (retryContext Context) 예외 {System.out.println ( "복구 작업"); 널 리턴; }}; 시도 {// retrytemplate.execute (retrycallback, recoverycallback)의 논리 실행을 시작하려면 retrytemplate에 의해 실행 메소드를 실행합니다. } catch (예외 e) {e.printstacktrace (); }}사례 코드를 간단히 분석 한 후, Retrytemplate은 재 시도 집행자의 역할을 가정합니다. 간단한 정책을 설정할 수 있습니다 (재시도 정책, 재시도 상한, 재 시도 루트 엔티티), FixedBackoffPolicy (고정 폴백 정책, 재시도 낙하를위한 시간 간격을 설정 함)를 설정할 수 있습니다. Retrytemplate은 실행을 통해 작업을 실행하며 2 개의 클래스 인스턴스 인 Retrycallback 및 RecoveryCallback의 두 가지 클래스 인스턴스가 두 개의 클래스 인스턴스를 준비해야합니다. 전자는 레트리 콜백 로직 인스턴스에 해당하며 정상적인 기능 연산을 감싸고 있습니다. RecoveryCallback은 전체 실행 작업의 끝에서 복구 작업 인스턴스를 구현합니다.
레트 리티 플레이트의 실행은 스레드-안전이며, 구현 로직은 ThreadLocal을 사용하여 각 실행 인스턴스의 리트리콘 텍스트 실행 컨텍스트를 저장합니다.
스프링 레트로 도구는 재 시도를 우아하게 구현할 수 있지만 두 가지 비우호적 인 디자인이 있습니다. 하나는 재 시도 엔티티가 던질 수있는 서브 클래스로 제한되어 있다는 것입니다. 이는 재 시도가 디자인 전제로서 기능적 예외를 목표로하지만, 데이터 객체 엔티티를 레트리 엔티티로 의존하고 싶지만, 스프링-평가 프레임 워크는 던지기 쉬운 서브 클래스에 의존해야합니다. 다른 하나는 근본 원인을 재 시도하는 어설 션 객체입니다. Dowithretry의 예외 예외 인스턴스를 사용하는데, 이는 정상적인 내부 어설 션의 반환 설계를 준수하지 않습니다.
스프링 레트리는 주석에서 재 시도 방법을 옹호합니다. 재 시도 로직은 동시에 실행됩니다. 재 시도의 "실패"는 Throwable을 목표로합니다. 반환 값의 특정 상태에 따라 재 시도 해야하는지 여부를 결정하려면 리턴 값을 직접 판단한 다음 명시 적으로 예외를 던질 수 있습니다.
재 시도에 대한 봄의 추상화
"초록"은 모든 프로그래머에게 필요한 품질입니다. 평범한 자격으로 저에게는 우수한 소스 코드를 모방하고 이해하는 것보다 개선 할 수있는 더 좋은 방법은 없습니다. 이를 위해, 나는 그 핵심 논리를 다시 작성합니다 ... "레트리"에 대한 Spring Retry의 추상화를 살펴 보겠습니다.
스프링 재시도 관련 인터페이스 .jpg
Guava Retryer 도구는 스프링 레트로와 유사합니다. 레트리의 역할을 정의하여 정상적인 논리적 재 시도를 감싸고 있습니다. 그러나 Guava Retryer는 더 나은 정책 정의를 가지고 있습니다. 레트리 시간 수와 재 시도 주파수 제어를 기준으로 여러 예외 또는 사용자 정의 엔티티 객체를 지원하는 재 시도 소스 정의와 호환 될 수 있으므로 재 시도 기능의 유연성을 높일 수 있습니다. 구아바 레트리어도 스레드 안전합니다. 항목 통화 로직은 java.util.concurrent.callable의 호출 방법을 사용합니다. 샘플 코드는 다음과 같습니다.
public void uploadodps (최종 맵 <문자열, 개체>지도) {// retryerBuilder 레트리 인스턴스 레트리를 구축하고 레트리 소스를 설정하고 여러 레트리 소스를 지원할 수 있습니다. 레트리 시간 수를 구성 할 수 있습니다. 재시도 시간 또는 재시험 시간 수를 구성 할 수 있습니다. .retryifexception () .// 설정 예외 재 시도 소스 retryifresult (new Prescticate <boolean> () {// 사용자 정의 세그먼트 재 시도 소스 설정, @override public boolean apply (부울 상태) {// 특수 참고 :이 적용은 Retry가 true를 반환한다는 것을 의미합니다. .withStopStrategy (stopStrations.stopfterattemp (5)) // 재 시도 5 번 설정하고, 재 시도 시간 초과 시간을 설정할 수도 있습니다 .WithWaitStrategy (waitstrategies.fixedwait (100L, TimeUnit.milliseconds); build (); retry 포털을 사용하여 콜 포털을 사용하여 {// java.util.concurrent.callable <v>, 실행은 실행은 스레드-안전한 boolean result = recult = retryer.call (new callable <boolean> () {@override public boolean call ()를 던지기 예외 {// special note {// special note : return true retrry retrry extrry (map); 예외 (e);}}}); } catch (executionException e) {} catch (retryexception ex) {}}샘플 코드 원리 분석 :
RetryerBuilder는 재 시도 소스를 사용자 정의 할 수 있으며 여러 레트리 소스를 지원할 수 있으며 재시도 시간 수를 구성하거나 재시도 시간 초과를 구성 할 수 있으며 대기 시간 간격을 구성하여 레트리 레지기 인스턴스를 생성 할 수있는 공장 제작자입니다.
RetryerBuilder의 Retry 소스는 예외 예외 객체 및 사용자 정의 어시스트 객체를 지원하며 Retryifexception 및 Retryifresult를 통해 설정되며 다중 기능을 지원하며 동시에 호환됩니다.
RetryerBuilder의 대기 시간 및 레트리 제한 구성은 서로 다른 정책 클래스를 사용하여 구현되며 대기 시간 기능은 Unintral 및 고정 간격 모드를 지원할 수 있습니다.
레트리어는 통화 메소드를 통해 작동 로직을 실행하고 레트리 소스 작업을 캡슐화하는 레트 리더의 인스턴스입니다.
우아한 재 시도 공통성과 원리
정상적이고 재 시도 우아하게 분리 된 재 시도는 조건부 인스턴스 또는 논리적 예외 인스턴스가 둘 사이의 통신을위한 매체라고 주장합니다.
재 시도 간격, 차등 재 시도 전략에 동의하고 재시도 시간 초과 시간을 설정하여 재 시도의 효과와 재 시도 프로세스의 안정성을 더욱 보장합니다.
모두 명령 설계 패턴을 사용하고 해당 논리적 작업은 재 시도 객체를 위임하여 완료되며 재 시도 로직은 내부적으로 구현됩니다.
Spring-Stryer 및 Guava-Stryer 도구는 스레드 안전 재 시도이며 동시 비즈니스 시나리오에서 레트리 논리의 정확성을 지원할 수 있습니다.
재 시도를위한 적용 가능한 시나리오
기능 논리에는 불안정한 종속성 시나리오가 있으며, 예상 결과를 얻거나 즉시 끝나지 않고 논리를 다시 실행하려면 재시도를 사용해야합니다. 예를 들어 원격 인터페이스 액세스, 데이터로드 액세스, 데이터 업로드 확인 등
예외 시나리오를 위해 다시 시도 해야하는 시나리오가 있으며 동시에 정상적인 논리와 레트리 논리를 분리하기를 희망합니다.
데이터 매체를 기반으로하는 상호 작용의 경우, 실행 논리를 감지하기 위해 재시도 폴링이 필요한 시나리오에서 재시도 체계를 고려할 수도 있습니다.
위의 내용은 Java 프로그래밍 재 시도 재 시도 메커니즘 예제에 대한 모든 자세한 설명입니다. 모든 사람에게 도움이되기를 바랍니다. 관심있는 친구는이 사이트의 다른 관련 주제를 계속 참조 할 수 있습니다. 단점이 있으면 메시지를 남겨 두십시오. 이 사이트를 지원해 주신 친구들에게 감사드립니다!