亚洲精品久久久中文字幕-亚洲精品久久片久久-亚洲精品久久青草-亚洲精品久久婷婷爱久久婷婷-亚洲精品久久午夜香蕉

您的位置:首頁(yè)技術(shù)文章
文章詳情頁(yè)

spring Retryable注解實(shí)現(xiàn)重試詳解

瀏覽:65日期:2023-08-13 13:31:21

spring-boot:1.5.3.RELEASE,spring-retry-1.2.0.RELEASE

使用方法

引入pom

// 版本號(hào)繼承spring-boot依賴管理的pom<dependency> <groupId>org.springframework.retry</groupId> <artifactId>spring-retry</artifactId></dependency><dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId></dependency>

啟用重試

@Configuration@ImportResource(locations = { 'classpath*:spring/app-context-*' })@EnableRetrypublic class AppContext {}

注解需要重試的方法

@Retryable(value = RuntimeException.class, maxAttempts = 3,backoff = @Backoff(delay = 10L, multiplier = 1))public boolean myRetryableMethod(){ ...}

注解屬性含義

Retryable

@Target({ ElementType.METHOD, ElementType.TYPE })@Retention(RetentionPolicy.RUNTIME)@Documentedpublic @interface Retryable { /** * 為重試方法應(yīng)用重試攔截器的bean名稱。與其他屬性互斥 */ String interceptor() default ''; /** * 可以重試的異常類型。與includes屬性同義。默認(rèn)值為空(并且如果exclude也是空的話, * 所有的異常都會(huì)重試) */ Class<? extends Throwable>[] value() default {}; /** * 同上 */ Class<? extends Throwable>[] include() default {}; /** * 與include含義相反 */ Class<? extends Throwable>[] exclude() default {}; /** * 統(tǒng)計(jì)報(bào)告的唯一標(biāo)簽。如果沒有提供,調(diào)用者可以選擇忽略它,或者提供一個(gè)默認(rèn)值。 * * @return the label for the statistics */ String label() default ''; /** * 標(biāo)識(shí)重試有狀態(tài)的:即異常重新拋出,但是重試策略使用相同的策略應(yīng)用于后續(xù)的具有相同參數(shù)的 * 調(diào)用。如果為false那么可重試的異常不會(huì)重新拋出。 */ boolean stateful() default false; /** * 嘗試的最大次數(shù)(包含第一次失敗),默認(rèn)為3 */ int maxAttempts() default 3; /** * 返回一個(gè)求嘗試最大次數(shù)值的表達(dá)式(包含第一次失敗),默認(rèn)為3 * 重寫 {@link #maxAttempts()}。 * @since 1.2 */ String maxAttemptsExpression() default ''; /** * 為正重試的動(dòng)作指定backoff屬性。默認(rèn)沒有backoff,但是在兩次嘗試之間暫定一下是一個(gè)很好的想法 * (即使代價(jià)是阻塞線程) */ Backoff backoff() default @Backoff(); /** * 在{@code SimpleRetryPolicy.canRetry()}返回true之后指定一個(gè)計(jì)算表達(dá)式 - 可用來有條件的取消重試。 * 僅在調(diào)用拋出一個(gè)異常后。求值的root對(duì)象為上一次的異常 {@code Throwable}。 * 可以引用上下文中的其他beans。 * 例如: * {@code 'message.contains(’you can retry this’)'}. * and * {@code '@someBean.shouldRetry(#root)'}. * @since 1.2 */ String exceptionExpression() default '';}

Backoff

@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)@Import(RetryConfiguration.class)@Documentedpublic @interface Backoff { /** * 與 {@link #delay()} 屬性同義 * * 返回延遲多少毫秒后重試(默認(rèn)為1000毫秒) */ long value() default 1000; /** * 一個(gè)標(biāo)準(zhǔn)的再重試周期。在指數(shù)函數(shù)情況下用作初始值,在始終如一的情況下(固定周期值情況) * 用作最小值。 * @return the initial or canonical backoff period in milliseconds (default 1000)??? */ long delay() default 0; /** * 重試之間最大等待(毫秒)時(shí)間。如果小于 {@link #delay()} 則忽略。 * @return the maximum delay between retries (default 0 = ignored) */ long maxDelay() default 0; /** * 如果是正數(shù),則用于生成下次再重試等待時(shí)間的乘數(shù)。 * 返回一個(gè)乘數(shù)用于計(jì)算下次再重試延遲(默認(rèn)為0忽略) */ double multiplier() default 0; /** * 標(biāo)準(zhǔn)再重試周期求值表達(dá)式。在指數(shù)情況下用作初始值,始終如一的情況下用作最小值。 * 重寫 {@link #delay()}. * @since 1.2 */ String delayExpression() default ''; /** * 在重試之間最大等待(毫秒)數(shù)的求值表達(dá)式。 * 如果小于 {@link #delay()} 則忽略。 * 重寫 {@link #maxDelay()} * 默認(rèn)為0,忽略 * @since 1.2 */ String maxDelayExpression() default ''; /** * 表達(dá)式求值作為生成下次再重試延遲的乘數(shù) * 重寫 {@link #multiplier()}。 * @since 1.2 */ String multiplierExpression() default ''; /** * 在指數(shù)情況下 ({@link #multiplier()} > 0) 設(shè)置該值為true將使再重試延遲隨機(jī)化, * 使最大延遲為先前延遲的乘數(shù)倍數(shù),并使這兩個(gè)延遲值之間分布均勻。 * 默認(rèn)為false */ boolean random() default false;}

案例

默認(rèn)retry

@Componentpublic class MyTask { @Retryable public void doExecute(){ System.out.println('## current Date:' + new Date()); throw new RuntimeException('my test'); }}

輸出結(jié)果

## current Date:Sat Aug 29 21:54:55 CST 2020 ## current Date:Sat Aug 29 21:54:56 CST 2020 ## current Date:Sat Aug 29 21:54:57 CST 2020 2020-08-29 21:55:00,319 INFO [main] com.dianwoba.common.datasource.DataSourceAspect:invoke:32 restore database connection Exception in thread 'main' java.lang.RuntimeException: my test ...

stateful

源碼相同,注解增加屬性配置

@Retryable( stateful = true )

public void doExecute(){

輸出結(jié)果

## current Date:Sat Aug 29 21:58:56 CST 2020 2020-08-29 21:58:57,557 INFO [main] com.dianwoba.common.datasource.DataSourceAspect:invoke:32 restore database connection Exception in thread 'main' java.lang.RuntimeException: my test // 沒有重新拋出異常觸發(fā)重試

該參數(shù)為false時(shí)會(huì)重試3次后拋出異常,重試期間不會(huì)重新拋出異常。參數(shù)為true時(shí)則重試期間也會(huì)重新拋出異常導(dǎo)致重試失敗不再繼續(xù)重試

backoff.multiplier

注解屬性配置

@Retryable( backoff = @Backoff( delay = 1000, multiplier = 2), maxAttempts = 10)

輸出結(jié)果

## current Date:Sat Aug 29 23:06:50 CST 2020 ## current Date:Sat Aug 29 23:06:51 CST 2020 ## current Date:Sat Aug 29 23:06:53 CST 2020 ## current Date:Sat Aug 29 23:06:57 CST 2020 ## current Date:Sat Aug 29 23:07:05 CST 2020 ## current Date:Sat Aug 29 23:07:21 CST 2020 ## current Date:Sat Aug 29 23:07:51 CST 2020 ## current Date:Sat Aug 29 23:08:21 CST 2020 ## current Date:Sat Aug 29 23:08:51 CST 2020 ## current Date:Sat Aug 29 23:09:21 CST 2020 2020-08-29 23:09:21,949 INFO [main] com.dianwoba.common.datasource.DataSourceAspect:invoke:32 restore database connection Exception in thread 'main' java.lang.RuntimeException: my test

乘數(shù)正確,指數(shù)型增長(zhǎng),第1次延遲1s

第2次,上次延遲1s乘以乘數(shù)2=延遲2s

第3次,上次延遲2s乘以乘數(shù)2=延遲4s

指數(shù)增長(zhǎng),如果沒有指定則為始終如一的固定間隔延遲類型。新版本已經(jīng)增加了各種類型單獨(dú)的屬性配置的模板構(gòu)建者:

RetryTemplate.builder() .maxAttempts(10) .exponentialBackoff(100, 2, 10000) .retryOn(IOException.class) .traversingCauses() .build();RetryTemplate.builder() .fixedBackoff(10) .withinMillis(3000) .build();RetryTemplate.builder() .infiniteRetry() .retryOn(IOException.class) .uniformRandomBackoff(1000, 3000) .build();

backoff.random

測(cè)試代碼

@Componentpublic class MyTask { private Long lastTime = null; @Retryable( backoff = @Backoff( delay = 1000, multiplier = 2, random = true), maxAttempts = 10) public void doExecute(){ if (lastTime == null) { lastTime = System.currentTimeMillis(); } System.out.println('## actual delay:' + (System.currentTimeMillis() - lastTime) ); RuntimeException runtimeException = new RuntimeException('my test'); throw runtimeException; }}

輸出結(jié)果

## current Date:Sat Aug 29 22:53:10 CST 2020## current Date:Sat Aug 29 22:53:11 CST 2020## current Date:Sat Aug 29 22:53:14 CST 2020## current Date:Sat Aug 29 22:53:20 CST 2020## current Date:Sat Aug 29 22:53:29 CST 2020## current Date:Sat Aug 29 22:53:51 CST 2020## current Date:Sat Aug 29 22:54:41 CST 2020## current Date:Sat Aug 29 22:55:25 CST 2020## current Date:Sat Aug 29 22:56:11 CST 2020## current Date:Sat Aug 29 22:57:01 CST 20202020-08-29 22:57:01,617 INFO [main] com.dianwoba.common.datasource.DataSourceAspect:invoke:32 restore database connectionException in thread 'main' java.lang.RuntimeException: my test

延遲更加隨機(jī)化,由于是最大延遲為之前延遲的乘數(shù)的倍數(shù),所以看不出規(guī)律。它的使用場(chǎng)景是使延遲更加隨機(jī)化

exceptionExpression

測(cè)試代碼

@Componentpublic class MyTask { private Long lastTime = null; public boolean canRetry(RuntimeException runtimeException) { System.out.println('canRetry:'+runtimeException.hashCode()); return true; } @Retryable(exceptionExpression = '#{@myTask.canRetry(#root)}', backoff = @Backoff(delay = 1000, multiplier = 2, random = true)) public void doExecute() { if (lastTime == null) { lastTime = System.currentTimeMillis(); } System.out.println('## actual delay:' + (System.currentTimeMillis() - lastTime)); RuntimeException runtimeException = new RuntimeException('my test'); System.out.println('doExecute:'+runtimeException.hashCode()); throw runtimeException; }}

輸出結(jié)果

## actual delay:0 doExecute:626562869 2020-08-29 23:50:49,905 DEBUG [main] com.dianwoba.common.datasource.DataSourceAspect:invoke:28 public boolean com.dianwoda.billing.settle.task.MyTask.canRetry(java.lang.RuntimeException) execute with datasource is master canRetry:626562869 2020-08-29 23:50:49,906 INFO [main] com.dianwoba.common.datasource.DataSourceAspect:invoke:32 restore database connection 2020-08-29 23:50:51,335 DEBUG [main] com.dianwoba.common.datasource.DataSourceAspect:invoke:28 public boolean com.dianwoda.billing.settle.task.MyTask.canRetry(java.lang.RuntimeException) execute with datasource is master canRetry:626562869 2020-08-29 23:50:51,336 INFO [main] com.dianwoba.common.datasource.DataSourceAspect:invoke:32 restore database connection ## actual delay:1450 doExecute:90418597 2020-08-29 23:50:51,337 DEBUG [main] com.dianwoba.common.datasource.DataSourceAspect:invoke:28 public boolean com.dianwoda.billing.settle.task.MyTask.canRetry(java.lang.RuntimeException) execute with datasource is master canRetry:90418597 2020-08-29 23:50:51,338 INFO [main] com.dianwoba.common.datasource.DataSourceAspect:invoke:32 restore database connection 2020-08-29 23:50:53,620 DEBUG [main] com.dianwoba.common.datasource.DataSourceAspect:invoke:28 public boolean com.dianwoda.billing.settle.task.MyTask.canRetry(java.lang.RuntimeException) execute with datasource is master canRetry:90418597 2020-08-29 23:50:53,620 INFO [main] com.dianwoba.common.datasource.DataSourceAspect:invoke:32 restore database connection ## actual delay:3734 doExecute:307531674 2020-08-29 23:50:53,621 INFO [main] com.dianwoba.common.datasource.DataSourceAspect:invoke:32 restore database connection Exception in thread 'main' java.lang.RuntimeException: my test

注意:1.2.5之后表達(dá)式的預(yù)發(fā)有所改變,詳情可以參考官方文檔:https://github.com/spring-projects/spring-retry

以上這篇spring Retryable注解實(shí)現(xiàn)重試詳解就是小編分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持好吧啦網(wǎng)。

標(biāo)簽: Spring
相關(guān)文章:
主站蜘蛛池模板: 国产aav | 拍拍视频免费观看网站在线观看 | aaa特级毛片 | 欧美大片一区 | 成人男女网免费 | 337d欧美人体大胆瓣开下面 | 日韩欧美一区二区三区四区 | 欧美日韩高清一本大道免费 | 麻豆国产精品va在线观看不卡 | 亚洲精品www | 亚洲国产二区三区 | 久久久精品国产免费观看同学 | 免费看三级毛片 | 免费一级毛片在线播放视频 | 国产又色又爽在线观看 | 欧美日韩在线观看免费 | 水蜜桃爱爱yy视频在线观看 | 国产亚洲精品国产第一 | 国产精品一区二区三区四区五区 | 国产精品久久久久国产精品 | 国产资源在线免费观看 | 久久婷婷国产综合精品青草 | 色综合久久中文色婷婷 | 欧美精品亚洲精品日韩 | 91影院在线观看 | 久久久亚洲国产精品主播 | 亚洲欧美中文日韩综合 | 亚洲欧洲精品久久 | 黄色录像一级片 | 青青操网 | 美国老黑一级毛片免费的大黄 | 日本一级毛片在线观看 | 国产精品视频牛仔裤一区 | 亚洲无吗视频 | 精品欧美一区二区三区在线观看 | 欧美999| 黄色网页视频 | 国产在线综合一区二区三区 | 九九黄色大片 | 亚洲欧美在线看 | 亚洲精选在线观看 |