1, introduction
In business development, it is likely to be the case of retrying.
Retry is mainly used when the call fails, especially when dubbo related exception and network related exception occur.
The following is a simple encapsulation of this function, and then gives some relatively more open source code addresses.
2. Simple package
github address https://github.com/chujianyun/simple-retry
Downloadable operation, fork improvement, welcome to provide valuable comments, welcome to contribute code.
Encapsulation operation
package com.chujianyun.simpleretry; /** * Operation interface method * * @author: Mingming Ruyue liuwangyanghudu@163.com * @date: 2019-04-05 02:09 */ public interface Operation<T> { T execute() throws Exception; }
Package retry
package com.chujianyun.simpleretry; import com.chujianyun.simpleretry.exception.BusinessException; import lombok.extern.slf4j.Slf4j; import java.util.concurrent.TimeUnit; /** * Operation encapsulation * * @author: Mingming Ruyue liuwangyanghudu@163.com * @date: 2019-04-05 02:09 */ @Slf4j public class OperationHelper { /** * Operation execution with retry * * @param operation Actions performed * @param maxAttemptTimes max retries * @param <T> return type * @return Return value * @throws Exception */ public static <T> T executeWithRetry(Operation<T> operation, int maxAttemptTimes) throws Exception { return executeWithRetry(operation, maxAttemptTimes, 0, null); } /** * Operation execution with retry and delay * * @param operation Actions performed * @param maxAttemptTimes max retries * @param timeDelay delayed * @param timeUnit Time unit * @param <T> return type * @return Return value * @throws Exception */ public static <T> T executeWithRetry(Operation<T> operation, int maxAttemptTimes, int timeDelay, TimeUnit timeUnit) throws Exception { if (maxAttemptTimes < 1) { throw new IllegalArgumentException("max attempt times must not less than one"); } int count = 1; while (true) { try { return operation.execute(); } catch (BusinessException businessException) { log.debug("OperationHelper#businessException", businessException); throw new BusinessException(); } catch (Exception e) { log.debug("OperationHelper#executeWithRetry", e); //Cumulative count++; if (count > maxAttemptTimes) { throw e; } // delayed if (timeDelay >= 0 && timeUnit != null) { try { log.debug("delayed{}Millisecond", timeUnit.toMillis(timeDelay)); timeUnit.sleep(timeDelay); } catch (InterruptedException ex) { //ignore } } log.debug("The first{}Second try", count - 1); } } } }
In case of business exception, there is no need to try again and throw it out directly.
When a non business exception is encountered and the maximum number of retries is not exceeded, retry continuously. If a delay is set, retry after a delay.
Test class
package com.chujianyun.simpleretry; import com.chujianyun.simpleretry.exception.BusinessException; import lombok.extern.slf4j.Slf4j; import org.junit.Test; import java.util.Random; import java.util.concurrent.TimeUnit; /** * Retry test * * @author: Mingming Ruyue liuwangyanghdu@163.com * @date: 2019-04-04 10:42 */ @Slf4j public class OperationHelperTest { @Test(expected = Exception.class) public void executeWithRetry_Exception() throws Exception { OperationHelper.executeWithRetry(() -> { throw new Exception(); }, 3, 5, TimeUnit.SECONDS); } @Test(expected = BusinessException.class) public void executeWithRetry_BusinessException() throws Exception { OperationHelper.executeWithRetry(() -> { throw new BusinessException(); }, 3, 5, TimeUnit.SECONDS); } @Test public void executeWithRetry() throws Exception { Integer result = OperationHelper.executeWithRetry(() -> { // If the random number is odd, the parameter is abnormal and will be retried Random random = new Random(); int nextInt = random.nextInt(100); if ((nextInt & 1) == 1) { log.debug("Generated random number{}It is an odd number. Retry will be triggered after an error is reported", nextInt); throw new IllegalArgumentException(); } return random.nextInt(5); }, 3, 5, TimeUnit.SECONDS); log.debug("Final return value{}", result); } }
3. Other plans
https://github.com/rholder/guava-retrying
https://github.com/elennick/retry4j