Today’s sharing started, please give us more advice ~

External services are generally unreliable for callers, especially in the case of poor network environment. Network jitter can easily lead to request timeout and other exceptions. In this case, you need to use the failed retry policy to re-invoke the API interface to obtain external services. Retry strategies are also widely used in service governance to check whether a service is alive or not through periodic checks.

Spring Exception Retry framework Spring Retry

Spring Retry supports integration into Spring or Spring Boot projects, and it supports AOP’s aspect injection writing, so the AspectJweaver. Jar package must be introduced.

1. Introduce Maven dependencies

2. Add the @retryable and @recover annotations

@retryable annotations are retried when an exception occurs over the annotated method

  • Value: specifies the exception to be retried

  • Include: Like value, is null by default. When exclude is also null, all exceptions are retried

  • Exclude: specifies that exceptions are not retried. The default value is null. If include is also empty, all exceptions are retried

  • Maxattem: Number of retries, default is 3

  • Backoff: the retry compensation mechanism is unavailable by default

@ Backoff annotations

  • Delay: Retry after the specified delay

  • Multiplier: Specifies the delay multiplier. For example, if delay= 5000L, Multiplier =2, the first retry is 5 seconds later, the second retry is 10 seconds, and the third retry is 20 seconds

@recover Annotation: When a specified number of retries are reached, the annotated method is called back and log processing can take place in the method. It is important to note that the callback occurs only when the exception is of the same type as the input parameter.

3. Enable retry

Add the @enableretry annotation on the startup class to EnableRetry, or on services that use retry, or on the Configuration class. It is recommended that all Enable configurations be added to the startup class to clearly unify the functions used.

4. Start the service and run the test

Guava-based retry component Guava-retryer

Look directly at the component author’s description of this component:

This is a small extension to Google’s Guava Library, which allows you to work with different retrying strategies Arbitrary function call, such as something that talks to a remote service with flaky uptime (arbitrary function call, such as something that talks to a remote service with flaky uptime) Allows you to create configurable retry policies for arbitrary function calls, such as those for conversations with remote services with unstable runtime.

Step 1 Introduce maven coordinates:

1. Main interfaces and strategies

  • Attempt to do STH.

  • AttemptTimeLimiter: Time limit for a single task (if a single task times out, the current task is terminated)

  • BlockStrategies: Task blocking strategies (generally speaking, what to do during the period when the current task is executed and the next task is not started… — blockstrategies. THREAD_SLEEP_STRATEGY call thread. sleep(sleepTime);

  • RetryException: RetryException.

  • RetryListener: a custom RetryListener that can be used to log errors asynchronously.

  • StopStrategy: stop retry policy, which can be:

  • StopAfterDelayStrategy: Set a maximum allowed execution time; For example, the maximum retry time is set to 10 seconds. If the retry time exceeds the maximum retry time, the task is terminated and RetryException is returned.

  • NeverStopStrategy: never stopping, used when rotating until the desired result is returned;

  • StopAfterAttemptStrategy: Sets the maximum number of retries. If the maximum number of retries is exceeded, the retries are stopped and a retry exception is returned.

  • WaitStrategy: wait time policy (control time interval), and the result is the next execution time:

  • FixedWaitStrategy: Fixed waiting time strategy;

  • RandomWaitStrategy: random waiting time strategy (can provide a minimum and maximum waiting time, the waiting time is their interval random value)

  • IncrementingWaitStrategy: Incrementing wait time strategy (provide an initial value and step size, wait time increases with retry count)

  • ExponentialWaitStrategy: ExponentialWaitStrategy;

  • FibonacciWaitStrategy: Fibonacci wait duration strategy.

  • ExceptionWaitStrategy: Wait policy for abnormal duration.

  • CompositeWaitStrategy: CompositeWaitStrategy;

2. Determine whether to retry based on the result

Usage scenario: If the return value determines whether to retry. Retry interface:

Testing:

Output:

3. Determine whether to retry based on the exception

Usage scenario: Determine whether to retry based on the type of exceptions thrown. Retry interface:

Testing:

Output:

4. Retry policy — Set unlimited retry

Usage scenario: In the case of exceptions, infinite retry (default execution policy) until a valid result is returned.

Retry policy – Sets the maximum number of retries

Usage scenario: If exceptions exist, the maximum number of retries is allowed. If the number of retries exceeds the threshold, an exception is thrown.

Testing:

Output:

6. Wait policy: Set a fixed retry wait period policy

Application scenario: Set the waiting interval for each retry to 10s.

Testing the output, we can see that the call interval is 10S:

7. Wait policy – Set a fixed growth policy for retry wait time

Scenario: Set the initial waiting time value and set a fixed growth step, but not set the maximum waiting time;

Test the output, it can be seen that the call interval is increased by 1 second:

8. Wait policy – Set a strategy to increase the retry wait time exponentially

Usage scenario: Increase the waiting time exponentially according to the Multiplier value and set the maximum waiting time;

This retry policy and entry is not very understand, well, check the source code:

ExponentialWaitStrategy is an immutable internal class through the source code, the constructor checks into the parameter, the most important delay time calculation method computeSleepTime(), we can see the delay time calculation

Calculate the number of failures as an exponent base 2

The value constructor for the first step multiplies the first input arguments and then rounds them to get the delay time in milliseconds

Based on the above analysis, it can be seen that the interval of 1000 input parameters should be 2, 4, and 8s

Test output, it can be seen that the call interval is 2×1000, 4×1000, 8×1000:

9. Wait policy – Set the retry wait time according to Fibonacci number policy

Usage scenario: Increase the wait time according to the Fibonacci sequence based on the multiplier value and set the maximum wait time. The Fibonacci sequence is 1, 1, 2, 3, 5, 8, 13, 21, 34…

The delay time is the product of the Fibonacci sequence and the first input parameter (milliseconds).

Test output, it can be seen that the interval call is 1×1000, 1×1000, 2×1000:

10. Wait policy – Combined retry wait duration policy

Application scenario: If existing policies do not meet application scenarios, multiple policies can be combined.

Again, look at the source code to understand what composition policies mean:

It can be seen that the delay time of the combination policy is obtained by adding the delay time of multiple policies. ExponentialWait delay is 2,4,8,16,32… , fixedWait delay is 2,2,2,2,2… , so the total delay time is 4,6,10,18,34…

Test output:

11. The RetryListener implements details of the retry process

Usage scenarios: Custom listeners that print details of the retry process separately, more for asynchronous logging, or special processing in the future.

Testing:

Output:

conclusion

Both approaches are elegant retry strategies. Spring-retry configuration is simpler and functions are relatively simple. Guava is a boutique Java library from Google, and guava-Retry is very powerful. Compared with spring-retry, it is more selective in determining whether to Retry and can be used as a supplement to spring-retry.

Today’s share has ended, please forgive and give advice!