Spring-Retry

About Retry

  Development often have to call the Api other projects, which may be the same company Api other teams or other companies, it can not avoid the network jitter call failure occurs, such cases tend to try again to normal. To add or update operation, if a non-idempotent operations, should be used with caution, Retry may cause abnormal operations.

You can use apache HttpClient or own implementation, spring also provides a retry mechanism Spring Retry.

GitHub address:  the Spring-Retry

There are two ways, and based on the coding mode based on the stated type, it is commonly used class diagram below:

FIG common class structure

Compensation / rollback strategy

Retry strategy

Retry context cache (strong references cited soft buffer mode)

Retry listener (notification function at different stages of realization)

The introduction of dependence

            <dependency>
                <groupId>org.springframework.retry</groupId>
                <artifactId>spring-retry</artifactId>
            </dependency>

Encoding

RetryTemplate Configuration

    @Bean(name = "retryTemplate")
    public RetryTemplate getRetryTemplate() {
        RetryTemplate template = new RetryTemplate();

        FixedBackOffPolicy backOffPolicy = new FixedBackOffPolicy();
        //设置2s重试一次
        backOffPolicy.setBackOffPeriod(2000);
        template.setBackOffPolicy(backOffPolicy);

        SoftReferenceMapRetryContextCache contextCache = new SoftReferenceMapRetryContextCache();
        template.setRetryContextCache(contextCache);

        SimpleRetryPolicy retryPolicy = new SimpleRetryPolicy();
        template.setRetryPolicy(retryPolicy);

        template.setThrowLastExceptionOnExhausted(true);
        return template;
    }

Do not specify RecoveryCallback 

    @Autowired RetryTemplate retryTemplate;
@RequestMapping(value
= "/test", method = { RequestMethod.GET }) public void test() { Boolean execute = retryTemplate.execute(ctx -> testMethod("arg-1", 12)); System.out.println("result : " + execute); } public Boolean testMethod(String arg1, Integer arg2) throws RuntimeException { logger.info("调用 testMethod 方法:arg1:" + arg1 + ",arg2:" + arg2); throw new RuntimeException("出错啦!"); }

Results of the:

2019-08-03 18: 23: 19.557 [INFO ] [http-nio-8097-exec-1]: c.demo.controller.DemoController [testMethod: 65] call testMethod Method: arg1: arg1, arg2: 12 
2019-08-03 18: 23: 21.563 [INFO ] [http-nio-8097-exec-1]: c.demo.controller.DemoController [testMethod: 65] call testMethod method: arg1: arg1, arg2: 12 
2019-08-03 18: 23: 23.563 [INFO ] [http-nio-8097-exec-1]: c.demo.controller.DemoController [testMethod: 65] call testMethod method: arg1: arg1, arg2: 12 
18 is 2019-08-03: 23 is: 23.567 [eRROR] [8097-HTTP-NiO--Exec. 1]: com.demo.CommonExceptionAdvice [processUnauthenticatedException: 45 ] 
java.lang.RuntimeException: it error!

Specify RecoveryCallback 

    @RequestMapping(value = "/test", method = { RequestMethod.GET })
    public void test() {
        Boolean execute = retryTemplate.execute(ctx -> testMethod("arg-1", 12), ctx -> callBack("arg-1", 12));
        System.out.println("result : " + execute);
    }

    public Boolean testMethod(String arg1, Integer arg2) throws RuntimeException {
        logger.info("调用 testMethod 方法:arg1:" + arg1 + ",arg2:" + arg2);
        throw new RuntimeException("出错啦!");
    }

    public Boolean callBack(String arg1, Integer arg2) throws RuntimeException {
        logger.info("调用 callBack 方法:arg1:" + arg1 + ",arg2:" + arg2);
        return false;
    }

Return result: 

2019-08-03 18: 39: 23.777 [INFO ] [http-nio-8097-exec-1]: c.demo.controller.DemoController [testMethod: 63] call testMethod Method: arg1: arg1, arg2: 12 
2019-08-03 18: 39: 25.781 [INFO ] [http-nio-8097-exec-1]: c.demo.controller.DemoController [testMethod: 63] call testMethod method: arg1: arg1, arg2: 12 
2019-08-03 18: 39: 27.781 [INFO ] [http-nio-8097-exec-1]: c.demo.controller.DemoController [testMethod: 63] call testMethod method: arg1: arg1, arg2: 12 
2019-08-03 18: 39: 27.781 [INFO ] [http-nio-8097-exec-1]: c.demo.controller.DemoController [callBack: 68] call callBack method: arg1: arg1, arg2: 12 
the Result: false 

Affirming comment

@Retryable comment 

Notes parameters:

value: abnormal retry designated occurred
include: and value as the default empty, when exclude also is empty, all exceptions are retried
exclude: Specifies the anomaly is not retried, the default empty, when include also is empty, all exceptions all retry
maxAttemps: retries, default 3
backoff: Retry compensation mechanism, there is no default 

    /**
     * Exception types that are retryable. Synonym for includes(). Defaults to empty (and
     * if excludes is also empty all exceptions are retried).
     * @return exception types to retry
     */
    Class<? extends Throwable>[] value() default {};

    /**
     * Exception types that are retryable. Defaults to empty (and if excludes is also
     * empty all exceptions are retried).
     * @return exception types to retry
     */
    Class<? extends Throwable>[] include() default {};

    /**
     * Exception types that are not retryable. Defaults to empty (and if includes is also
     * empty all exceptions are retried).
     * @return exception types to retry
     */
    Class<? extends Throwable>[] exclude() default {};

    /**
     * @return the maximum number of attempts (including the first failure), defaults to 3
     */
    int maxAttempts() default 3;

    /**
     * Specify the backoff properties for retrying this operation. The default is no
     * backoff, but it can be a good idea to pause between attempts (even at the cost of
     * blocking a thread).
     * @return a backoff specification
     */
    Backoff backoff() default @Backoff();
View Code

@Backoff

value: and the same delay, as the initial value in the case of exponentially
maxDelay: maximum time between retries is less than the delay, is ignored
multiplier: if positive, is used as the delay time is generated by a compensation number, the default value of 0 means ignore (eg: 2, first delay * 2 second time delay * 2 * 2)

    /**
     * Synonym for {@link #delay()}.
     *
     * @return the delay in milliseconds (default 1000)
     */
    long value() default 1000;

    /**
     * A canonical backoff period. Used as an initial value in the exponential case, and
     * as a minimum value in the uniform case.
     * @return the initial or canonical backoff period in milliseconds (default 1000)
     */
    long delay() default 0;

    /**
     * The maximimum wait (in milliseconds) between retries. If less than the
     * {@link #delay()} then ignored.
     *
     * @return the maximum delay between retries (default 0 = ignored)
     */
    long maxDelay() default 0;

    /**
     * If positive, then used as a multiplier for generating the next delay for backoff.
     *
     * @return a multiplier to use to calculate the next backoff delay (default 0 =
     * ignored)
     */
    double multiplier() default 0;

    /**
     * An expression evaluating to the canonical backoff period. Used as an initial value
     * in the exponential case, and as a minimum value in the uniform case.
     * Overrides {@link #delay()}.
     * @return the initial or canonical backoff period in milliseconds.
     * @since 1.2
     */
    String delayExpression() default "";

    /**
     * An expression evaluating to the maximimum wait (in milliseconds) between retries.
     * If less than the {@link #delay()} then ignored.
     * Overrides {@link #maxDelay()}
     *
     * @return the maximum delay between retries (default 0 = ignored)
     * @since 1.2
     */
    String maxDelayExpression() default "";

    /**
     * Evaluates to a vaule used as a multiplier for generating the next delay for backoff.
     * Overrides {@link #multiplier()}.
     *
     * @return a multiplier expression to use to calculate the next backoff delay (default 0 =
     * ignored)
     * @since 1.2
     */
    String multiplierExpression() default "";

    /**
     * In the exponential case ({@link #multiplier()} &gt; 0) set this to true to have the
     * backoff delays randomized, so that the maximum delay is multiplier times the
     * previous delay and the distribution is uniform between the two values.
     *
     * @return the flag to signal randomization is required (default false)
     */
    boolean random() default false;
View Code

Examples 

Plus the main class @EnableRetryannotation indicating enable retry mechanism.

@EnableRetry
@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

Specified exceptions and retry retry index 

    public Boolean testMethod(String arg1, Integer arg2) throws RuntimeException {
        logger.info("调用 testMethod 方法:arg1:" + arg1 + ",arg2:" + arg2);
        throw new RuntimeException("出错啦!");
    }

    @RequestMapping(value = "/testAn/{arg1}/{arg2}", method = { RequestMethod.GET })
    @Retryable(value = {Exception.class, RuntimeException.class}, backoff = @Backoff(multiplier = 1.5))
    public Boolean testExe(@PathVariable("arg1") String arg1, @PathVariable("arg2") Integer arg2) {
        Boolean result = testMethod(arg1, arg2);
        System.out.println("result : " + result);
        return result;
    }

    @Recover
    public Boolean backOffMethod(RuntimeException ex, String arg1, Integer arg2) {
        logger.info("调用 backOffMethod 方法:arg1:" + arg1 + ",arg2:" + arg2);
        return false;
    }

Retry results 

2019-08-07 15: 24: 31.790 [INFO ] [http-nio-8097-exec-8]: c.ppdai.koocapp.web.controller.SysCheckController [testMethod: 51] [eca27f812e304ec0964ddff868c1c98c] testMethod method call: arg1: Annotation-Test, arg2: 12 is 
2019-08-07 15: 24: 32.791 [the INFO] [8097-HTTP-NiO--Exec. 8]: c.ppdai.koocapp.web.controller.SysCheckController [testMethod: 51 is] [eca27f812e304ec0964ddff868c1c98c ] testMethod method call: arg1: Test-Annotation, arg2: 12 is 
2019-08-07 15: 24: 34.291 [the INFO] [8097-HTTP-NiO--Exec. 8]: c.ppdai.koocapp.web.controller.SysCheckController [testMethod: 51] [eca27f812e304ec0964ddff868c1c98c] testMethod method call: arg1: Test-Annotation, arg2: 12 is 
2019-08-07 15: 24: 34.292 [the INFO] [8097-HTTP-NiO--Exec. 8]: c.ppdai. koocapp.web.controller.SysCheckController [backOffMethod: 71] [eca27f812e304ec0964ddff868c1c98c ] backOffMethod method call: arg1: test-annotation, arg2 : 12

 

Guess you like

Origin www.cnblogs.com/mr-yang-localhost/p/11247286.html