spring retry基于aop,重试限制较多,基于抛出的异常进行重试,如果客户端把异常捕获了,没有抛出,重试就会失效。
guava retrying可以基于异常、基于返回结果做重试,即使客户端捕获异常,照样可以重试
使用灵活,目前没发现现有注解使用,只能自己封装工具类
package com.yintech.yk.secret.api.utils;
import com.github.rholder.retry.Retryer;
import com.github.rholder.retry.RetryerBuilder;
import com.github.rholder.retry.StopStrategies;
import com.github.rholder.retry.WaitStrategies;
import com.yintech.yk.secret.api.listener.VaultRetryListener;
import org.springframework.vault.VaultException;
import org.springframework.web.client.ResourceAccessException;
import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;
public class GuavaRetryer<T> {
private GuavaRetryer(){}
/**
* 初始化重试实例
*/
public static<T> Retryer<T> GuavaRetryer(){
Retryer retryer = RetryerBuilder.<T>newBuilder()
.retryIfExceptionOfType(VaultException.class)
.retryIfExceptionOfType(ResourceAccessException.class)
//重调等待时间
.withWaitStrategy(WaitStrategies.fixedWait(200, TimeUnit.MILLISECONDS))
//尝试次数
.withStopStrategy(StopStrategies.stopAfterAttempt(3))
//重试监听器
.withRetryListener(new VaultRetryListener())
.build();
return retryer;
}
/**
* 执行可重试方法
* @param callable
* @return
* @throws Exception
*/
public static<T> T executeWithRetry(Callable<T> callable) throws Exception {
Retryer<T> retryer = GuavaRetryer();
return retryer.call(callable);
}
}
/**
* AES解密
* @param cipherText 密文
* @return 明文
*/
protected static String decryptByAes(String cipherText) throws Exception {
VaultInfoCache instance = VaultInfoCache.getInstance();
return GuavaRetryer.executeWithRetry(()-> {
VaultTransitOperations vaultTransitOperations = instance.getVaultTemplate().opsForTransit(instance.getCacheMap()
.get(SecretConstants.PATH_KEY));
String keyName = instance.getCacheMap().get(String.format(SecretConstants.AES_KEY_NAME,
secretProperties.getSystemCode()));
return vaultTransitOperations.decrypt(keyName, cipherText);
});
}
参考资料
重试机制!java retry(重试) spring retry, guava retrying 详解 - JavaShuo