新增操作 失败后重试_可重试的操作
新增操作 失敗后重試
在我從事的每個項目中,始終需要某些功能:重試操作。 通常,這是關于通過網絡的呼叫,該呼叫可能一次失敗,但隨后會成功。 它可能涉及許多其他內容,主要包括與另一個系統的通信(無論是否通過網絡)。 它的功能,你絕對需要在大多數應用中,特別是如果你想他們是高可用性( 如這里指出的 ,例如)。
每次我必須在項目中引入此功能時,我都會檢查我們已導入的標準庫,沒有這樣的東西。 因此,我總是最終將我以前的項目中的同一段代碼復制粘貼。 我什至不記得我是什么時候第一次介紹它的,但是從那以后我就在“旅行”。 所以這里是:
/*** Class that provides retrying functionality. Example:* <p></p>* <code>* Callable<String> callable = new Callable<String>() {..};* String result = RetryableOperation.create(callable).retry(5, IOException.class);* </code>** @param <T> the return type of the operation*/ public class RetryableOperation<T> {private Callable<T> callable;private Runnable runnable;private boolean exponentialBackoff;private int backoffInterval = 500;/*** Create a retryable operation based on a Callable instance. The return* type of retry(..) is the type parameter of the Callable instance.** @param callable* @return* a new instance of RetryableOperation*/public static <T> RetryableOperation<T> create(Callable<T> callable) {return new RetryableOperation<T>().withCallable(callable);}/*** Creates a retryable operation based on a Runnable instance. In this case* the retry(..) method always returns null.** @param runnable* @return* a new instance of RetryableOperation*/public static RetryableOperation<?> create(Runnable runnable) {return new RetryableOperation<Object>().withRunnable(runnable);}/*** Retries the operation. Retrying happens regardless of the exception thrown.** @param retries* number of retries before the exception is thrown to the caller* @param exceptions* the operation will be retried only if the exception that occurs is one of the* exceptions passed in this array* @return* the result of the operation (null if Runnable is used instead of Callable)* @throws Exception* the exception that occurred on the last attempt*/public T retry(int retries, Class<? extends Exception>... exceptions) throws Exception {if (callable == null && runnable == null) {throw new IllegalStateException("Either runnable or callable must be set");}Set<Class<? extends Exception>> retryFor = new HashSet<Class<? extends Exception>>();retryFor.addAll(Arrays.asList(exceptions));for (int i = 0; i < retries; i++) {try {if (exponentialBackoff && i > 0) {int sleepTime = (int) ((Math.pow(2, i) - 1) / 2) * backoffInterval;Thread.sleep(sleepTime);}if (callable != null) {return callable.call();} else if (runnable != null) {runnable.run();return null;}} catch (Exception e) {if (retryFor.isEmpty() || retryFor.contains(e.getClass())) {if (i == retries - 1) {throw e;}} else {// if the exception is not the expected one, throw it immediatelythrow e;}}}// can't be reached - in case of failure on the last iteration the exception is rethrownreturn null;}private RetryableOperation<T> withCallable(Callable<T> callable) {this.callable = callable;return this;}private RetryableOperation<T> withRunnable(Runnable runnable) {this.runnable = runnable;return this;}public RetryableOperation<T> withExponentialBackoff() {this.exponentialBackoff = true;return this;} } 1這很簡單,但是效果很好。 您可以重試每個失敗,也可以重試特定的異常(您不想重試NullPointerException,但是必須配置適當的超時,然后重試網絡故障):
Result result = op.retry(3);...Result result = op.retry(3, IOException.class);我什至曾建議番石榴將其包含在內,然后再看其他類似的提案,但據我所知,番石榴或apache commons中都沒有這種功能。 而且我不會創建一個新的github項目,因為那將需要在maven Central中管理一個條目,而對于單個實用程序類來說,這是一項很大的工作。
當然,還有其他解決方法,它們具有更大的API和占用空間- 重試番石榴擴展和最近提取為單獨的項目spring-retry 。 它們值得檢查,并且具有要導入的Maven依賴項。
無論選擇什么選項,請檢查它是否支持匿名功能(自Java 8起)。 它可能會自動執行,但仍會檢查。
關鍵是要通過一個非常簡單的API來提供此功能,以便您可以避免用戶可避免的故障-必須重試幾次對外部系統的調用。
翻譯自: https://www.javacodegeeks.com/2015/10/retryable-operations.html
新增操作 失敗后重試
總結
以上是生活随笔為你收集整理的新增操作 失败后重试_可重试的操作的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: swagger生成示例_生成器设计模式示
- 下一篇: 我的集中隔离14天什么情况要集中隔离14