自动重试guava-retrying

一、概述

在日常开发中,接口调用异常是经常会遇到的,任何接口都会有不同情况的异常情况,对于可以重试的接口,为了避免偶发异常造成的接口的不可用,重试机制就非常有必要了。

二、常用重试组件

1、guava-retrying

2、spring retry

三、guava-retrying使用介绍

1、maven引入

<dependency>
	<groupId>com.github.rholder</groupId>
	<artifactId>guava-retrying</artifactId>
	<version>2.0.0</version>
</dependency>

2、demo

public static void main(String[] args) throws Exception {
        Retryer<Boolean> retryer = RetryerBuilder.<Boolean>newBuilder()
                .retryIfResult(Predicates.equalTo(false))
                .retryIfException()
                .withWaitStrategy(WaitStrategies.fixedWait(1, TimeUnit.SECONDS))
                .withStopStrategy(StopStrategies.stopAfterAttempt(5))
                .withRetryListener(new MyRetryListener<>())
                .build();
        try {
            retryer.call(()->{
                //call something
                return true;
            });
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

  

3、基于AOP方式使用

3.1 定义注解类

import java.lang.reflect.Method;
import java.util.concurrent.TimeUnit;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * guava retrying 注解使用
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface GuavaRetrying {
    //异常
    Class[] exceptionClass() default {};

    //重试次数
    int attemptNumber() default 0;

    //等待时间
    long waitStrategySleepTime() default 0;

    //持续时间; 期间
    long duration() default 0;
}

3.2 AOP类

import com.github.rholder.retry.RetryerBuilder;
import com.github.rholder.retry.StopStrategies;
import com.github.rholder.retry.WaitStrategies;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Service;

@Aspect
@Service
public class GuavaRetryingAspect {

    @Around(value = "@annotation(com.smart.service.aop.GuavaRetrying)")
    public Object monitorAround(ProceedingJoinPoint pjp) throws Throwable {
        Method method;
        if (pjp.getSignature() instanceof MethodSignature) {
            MethodSignature signature = (MethodSignature) pjp.getSignature();
            method = signature.getMethod();
        } else {
            return null;
        }

        GuavaRetrying annotation = method.getDeclaredAnnotation(GuavaRetrying.class);
        //重试时间,重试次数
        if (annotation.duration() <= 0 && annotation.attemptNumber() <= 1) {
            return pjp.proceed();
        }

        RetryerBuilder builder = RetryerBuilder.newBuilder();

        //重试次数
        if (annotation.attemptNumber() > 0) {
            builder.withStopStrategy(StopStrategies.stopAfterAttempt(annotation.attemptNumber()));
        }
        //退出策略
        if (annotation.duration() > 0) {
            builder.withStopStrategy(StopStrategies.stopAfterDelay(annotation.duration(), TimeUnit.MILLISECONDS));
        }

        //重试间间隔等待策略
        if (annotation.waitStrategySleepTime() > 0) {
            builder.withWaitStrategy(WaitStrategies.fixedWait(annotation.waitStrategySleepTime(), TimeUnit.MILLISECONDS));
        }

        //停止重试的策略
        if (annotation.exceptionClass().length > 0) {
            for (Class retryThrowable : annotation.exceptionClass()) {
                if (retryThrowable != null && Throwable.class.isAssignableFrom(retryThrowable)) {
                    builder.retryIfExceptionOfType(retryThrowable);
                }
            }
        }

        return builder.build().call(() -> {
            try {
                return pjp.proceed();
            } catch (Throwable throwable) {
                throw new Exception(throwable);
            }
        });
    }
}

  

3.3 使用实例

@GuavaRetrying(exceptionClass = RemoteException.class, attemptNumber = 2)
public Product getProductById(Long pId) {
	try {
		Product product = productService.getProductById(pId);
		
		return result;
	} catch (Exception e) {
		throw new RemoteException(e, null);
	}
}

  

  

  

猜你喜欢

转载自www.cnblogs.com/dztt/p/12364550.html
今日推荐