春天猫rtsy_春天重试,因为冬天来了
春天貓rtsy
好的,這實(shí)際上與冬天無(wú)關(guān),眾所周知,冬天已經(jīng)到了 。 它與Spring Retry有關(guān),Spring Retry是一個(gè)小的Spring框架庫(kù),它使我們可以向應(yīng)重試的任何任務(wù)添加重試功能。
這里有一個(gè)很好的教程 ,解釋了如何設(shè)置簡(jiǎn)單的重試和恢復(fù)。 它很好地解釋了如何添加spring-retry依賴項(xiàng) ,使用@Retryable和@Recover批注以及將RetryTemplate與簡(jiǎn)單策略一起使用。 當(dāng)我們實(shí)際上想根據(jù)異常的類(lèi)型應(yīng)用不同的重試行為時(shí),我想講的是一個(gè)稍微復(fù)雜的情況。 這是有道理的,因?yàn)槲覀兛赡苤滥承┊惓J强苫謴?fù)的,而某些異常是不可恢復(fù)的,因此嘗試從異常中恢復(fù)并沒(méi)有太大的意義。 為此,有一個(gè)特定的重試策略實(shí)現(xiàn),稱為ExceptionClassifierRetryPolicy ,與Spring RetryTemplate一起使用 。
假設(shè)我們只能從IO異常中恢復(fù)并跳過(guò)所有其他異常 。 我們將創(chuàng)建三個(gè)類(lèi)來(lái)擴(kuò)展RetryCallback,并創(chuàng)建一個(gè)類(lèi)來(lái)擴(kuò)展RecoveryCallback以更好地顯示內(nèi)部發(fā)生的情況:
private class SuccessCallback implements RetryCallback<Boolean, RuntimeException> {@Overridepublic Boolean doWithRetry(RetryContext context) throws RuntimeException {System.out.println("Success callback: attempt " + context.getRetryCount());return true;}}private class ExceptionCallback implements RetryCallback<Boolean, Exception> {@Overridepublic Boolean doWithRetry(RetryContext context) throws Exception {System.out.println("Exception callback: attempt " + context.getRetryCount());throw new Exception("Test Exception");}}private class SpecificExceptionCallback implements RetryCallback<Boolean, IOException> {@Overridepublic Boolean doWithRetry(RetryContext context) throws IOException {System.out.println("IO Exception callback: attempt " + context.getRetryCount());throw new IOException("Test IO Exception");}}private class LoggingRecoveryCallback implements RecoveryCallback<Boolean> {@Overridepublic Boolean recover(RetryContext context) throws Exception {System.out.println("Attempts exhausted. Total: " + context.getRetryCount());System.out.println("Last exception: " + Optional.ofNullable(context.getLastThrowable()).orElse(new Throwable("No exception thrown")).getMessage());System.out.println("\n");return false;}}然后,我們?cè)O(shè)置RetryTemplate 。 我們將使用SimpeRetryPolicy和IOException的固定嘗試次數(shù),以及一個(gè)NeverRetryPolicy ,它僅允許對(duì)其他所有事物進(jìn)行初始嘗試。
*We want to retry on IOException only.Other Exceptions won't be retried.IOException will be retried three times, counting the initial attempt.*/final ExceptionClassifierRetryPolicy exRetryPolicy = new ExceptionClassifierRetryPolicy();exRetryPolicy.setPolicyMap(new HashMap<Class<? extends Throwable>, RetryPolicy>() {{put(IOException.class, new SimpleRetryPolicy(3));put(Exception.class, new NeverRetryPolicy());}});retryTemplate.setRetryPolicy(exRetryPolicy);現(xiàn)在,我們需要使用這些回調(diào)來(lái)演示它們?nèi)绾喂ぷ鳌?首先成功執(zhí)行,這很簡(jiǎn)單:
// we do not catch anything hereSystem.out.println("\n*** Executing successfull callback...");retryTemplate.execute(new SuccessCallback(), new LoggingRecoveryCallback());其輸出如下:
*** Executing successfull callback... Success callback: attempt 0然后是異常 :
// we catch Exception to allow the program to continueSystem.out.println("\n*** Executing Exception callback...");try {retryTemplate.execute(new ExceptionCallback(), new LoggingRecoveryCallback());} catch (Exception e) {System.out.println("Suppressed Exception");}*** Executing Exception callback... Exception callback: attempt 0 Attempts exhausted. Total: 1 Last exception: Test Exception最后是我們的IOException :
// we catch IOException to allow the program to continueSystem.out.println("\n*** Executing IO Exception callback...");try {retryTemplate.execute(new SpecificExceptionCallback(), new LoggingRecoveryCallback());} catch (IOException e) {System.out.println("Suppressed IO Exception");}*** Executing IO Exception callback... IO Exception callback: attempt 0 IO Exception callback: attempt 1 IO Exception callback: attempt 2 Attempts exhausted. Total: 3 Last exception: Test IO Exception如我們所見(jiàn),只有IOException發(fā)起了三個(gè)嘗試。 請(qǐng)注意,嘗試次數(shù)從0開(kāi)始編號(hào),因?yàn)閳?zhí)行回調(diào)時(shí)嘗試次數(shù)并未耗盡,因此上一次嘗試次數(shù)為#2,而不是#3。 但是在RecoveryCallback上所有嘗試均已用盡,因此上下文保留3次嘗試。
我們還可以看到,嘗試成功后未調(diào)用RecoveryCallback 。 也就是說(shuō),僅當(dāng)執(zhí)行以異常結(jié)束時(shí)才調(diào)用它。
RetryTemplate是同步的,因此所有執(zhí)行都在我們的主線程中進(jìn)行。 這就是為什么我在調(diào)用周?chē)砑恿藅ry / catch塊的原因,以使程序可以毫無(wú)問(wèn)題地運(yùn)行所有三個(gè)示例。 否則,重試策略將在上次失敗嘗試后將異常拋出,并停止執(zhí)行。
還有一個(gè)非常有趣的CompositeRetryPolicy ,它允許添加幾個(gè)策略并委托來(lái)依次調(diào)用它們。 它還可以允許創(chuàng)建相當(dāng)靈活的重試策略,但這本身就是另一個(gè)主題。
我認(rèn)為spring-retry是一個(gè)非常有用的庫(kù),它可以使常見(jiàn)的可重試任務(wù)更可預(yù)測(cè),可測(cè)試且更易于實(shí)現(xiàn)。
翻譯自: https://www.javacodegeeks.com/2017/07/spring-retry-winter-coming.html
春天貓rtsy
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來(lái)咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)總結(jié)
以上是生活随笔為你收集整理的春天猫rtsy_春天重试,因为冬天来了的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 安卓外星人a16(安卓外星人)
- 下一篇: 济南车备案要预约吗(济南车备案)