日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

java 重试_Java重试机制修改

發布時間:2024/1/23 java 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java 重试_Java重试机制修改 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

最近無意間看到了一段代碼,實話實說看的我有點難受,剛開始的時候還略微有點懵,只是感覺代碼很長。等我捋了一遍之后,發現是一段調用遠程接口,失敗進行重試功能的代碼。代碼如下:

image.png

方法用到了遞歸,在重試次數小于零跳出。

說一下存在的問題吧:

接口重試和業務本身不發生關系,所以具有很高的耦合性

方法采用遞歸實現,有棧溢出的風險

重試邏輯無法進行重用

可配置性比較低

看下怎么改一下:

-抽離出重試代碼,預留接口,業務代碼填入,抽離工具類如下:

public abstract class MyRetryTemplate {

//重試次數

private int retryTime;

//重試時間

private int sleepTime;

//是否倍數增長

private boolean multiple = false;

/**

* 執行業務方法邏輯,由實現類實現

*

* @return

*/

public abstract T remote() throws Exception;

public T execute() throws InterruptedException {

for (int i = 1; i < retryTime + 1; i++) {

try {

return remote();

} catch (Exception e) {

System.out.println(e.getMessage());

if (multiple){

Thread.sleep(sleepTime);

}

else{

Thread.sleep(sleepTime * (i));

}

}

}

return null;

}

public T submit(ExecutorService executorService) {

Future submit = executorService.submit((Callable) () -> execute());

try {

return (T) submit.get();

} catch (InterruptedException | ExecutionException e) {

e.printStackTrace();

}

return null;

}

public MyRetryTemplate setRetryTime(int retryTime) {

this.retryTime = retryTime;

return this;

}

public MyRetryTemplate setSleepTime(int sleepTime) {

this.sleepTime = sleepTime;

return this;

}

public MyRetryTemplate setMultiple(boolean multiple) {

this.multiple = multiple;

return this;

}

}

上面的類中,值定義了重試的次數,間隔的時間,和時間的增長參數,預留了remote()抽象方法,交由具體的實現類來實現。類中使用了泛型,支持返回不同的對象。并且支持同步和異步調用。

看下修改后的代碼,如下:

image.png

是不是感覺一下清爽了很多,這里重試相關的參數,我直接寫死在了代碼中,可以通過配置文件和數據庫配置引入。這個方法應該還能精簡,最后兩句感覺還是有點多余,由于不知道是干啥的, 就暫且留在這吧。

修改后的代碼,雖然解決了一些上面的問題,但是并沒有完全解決,代碼的侵入性,上面已經說了既然這是重試的邏輯,就不應該出現在代碼中。有沒有解決的辦法呢,有,切面。

下面看下通過切面該怎么實現。

首先定義一個注解:

@Documented

@Target(ElementType.METHOD)

@Retention(RetentionPolicy.RUNTIME)

public @interface Retry {

int count() default 0 ;

long sleep() default 0 ;

}

定義切面

@Aspect

@Component

public class RetryAspect {

ExecutorService executorService = Executors.newFixedThreadPool(3);

@Around(value = "@annotation(Retry)")

public Object execute(ProceedingJoinPoint point, Retry retry) throws InterruptedException {

System.out.println("----------------- Aspect ---------------------");

MyRetryTemplate myRetryTemplate = new MyRetryTemplate() {

@Override

public ParametersHolder remote() throws Throwable {

return (ParametersHolder) point.proceed();

}

}.setRetryTime(3).setSleepTime(10000).submit(executorService);

return submit;

}

}

最終實現:

image.png

在注解中,添加自定義的參數,便可以實現零侵入,也更容易實現方法的復用,如果有其他的業務需要實現重試,直接在業務方法上添加注解即可。

如果不想用這種方法,也可以借助第三方工具guava-retrying和 spring-retry 來實現此功能。

總結

以上是生活随笔為你收集整理的java 重试_Java重试机制修改的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。