guava的重试机制guava-retrying使用
1,添加maven依赖
<dependency> <groupId>com.github.rholder</groupId> <artifactId>guava-retrying</artifactId> <version>2.0.0</version> </dependency>
2,定义重试机制
Retryer<CMSResultDTO> smsRetryer = RetryerBuilder.<CMSResultDTO>newBuilder() .retryIfResult(cmsResultDTO->cmsResultDTO.getCode() != SM_SUCCESS_CODE) // 短信返回的码不是200要重试 .retryIfResult(Predicates.<CMSResultDTO>isNull()) // 返回的数据是null要重试 .retryIfExceptionOfType(Exception.class) // 返回的异常错误类 .withStopStrategy(StopStrategies.stopAfterAttempt(ATTEMPT_NUM)) .withWaitStrategy(WaitStrategies.fixedWait(SLEEP_TIME, TimeUnit.SECONDS)) // 隔1秒重试 .withRetryListener(new SMRetryListener<>()) .build();
3,定义要重试的任务
Callable<CMSResultDTO> task = ()->{ log.info("sm input param:type=>{}, interCode=>{}, mobile=>{}, pair=>{}", type, interCode, mobile, pair); CMSResultDTO cmsResultDTO = cmsService.sendMessage(type, interCode, mobile, pair); log.info("sm return data:{}", JSON.toJSONString(cmsResultDTO)); return cmsResultDTO; };
4,重试机制重试任务
CMSResultDTO cmsResultDTO = null; try { cmsResultDTO = smsRetryer.call(task); } catch (ExecutionException e) { log.error("SM ExecutionException", e); } catch (RetryException e) { log.error("SM RetryException", e); } return cmsResultDTO;
以下是一个关于重试发短信的完整例子
/** * 重试机制 发送短信接口支持国际码 * @param type 模版号 * @param interCode 国际码 * @param mobile 手机号码 * @param pair 参数对 * @return 消息发送结果,包括发送状态和消息标识 */ public CMSResultDTO retrySendMessage(Integer type, String interCode, String mobile, Map<String, String> pair) throws CMSQueueException, CMSSendException { Preconditions.checkNotNull(type, "type不能为null"); Preconditions.checkNotNull(interCode, "interCode不能为null"); Preconditions.checkNotNull(mobile, "mobile不能为null"); Preconditions.checkNotNull(pair, "pair不能为null"); Callable<CMSResultDTO> task = ()->{ log.info("sm input param:type=>{}, interCode=>{}, mobile=>{}, pair=>{}", type, interCode, mobile, pair); //调用第三方发短信接口,得到返回值,第一时间记录到log中 CMSResultDTO cmsResultDTO = cmsService.sendMessage(type, interCode, mobile, pair); log.info("sm return data:{}", JSON.toJSONString(cmsResultDTO)); return cmsResultDTO; }; //定义重试的机制原理 Retryer<CMSResultDTO> smsRetryer = RetryerBuilder.<CMSResultDTO>newBuilder() .retryIfResult(cmsResultDTO->cmsResultDTO.getCode() != SM_SUCCESS_CODE) // 短信返回的码不是200要重试 .retryIfResult(Predicates.<CMSResultDTO>isNull()) // 返回的数据是null要重试 .retryIfExceptionOfType(Exception.class) // 返回的异常错误类 .withStopStrategy(StopStrategies.stopAfterAttempt(ATTEMPT_NUM)) .withWaitStrategy(WaitStrategies.fixedWait(SLEEP_TIME, TimeUnit.SECONDS)) // 隔1秒重试 //监听器 .withRetryListener(new SMRetryListener<>()) .build(); CMSResultDTO cmsResultDTO = null; try { //执行任务的重试,得到返回结果 cmsResultDTO = smsRetryer.call(task); } catch (ExecutionException e) { log.error("SM ExecutionException", e); } catch (RetryException e) { log.error("SM RetryException", e); } return cmsResultDTO; } //自定义的监听器 /** * 重试监听器 * @param <CMSResultDTO> */ private class SMRetryListener<CMSResultDTO> implements RetryListener { @Override public <CMSResultDTO> void onRetry(Attempt<CMSResultDTO> attempt) { log.info("[retry]time=" + attempt.getAttemptNumber()); if (attempt.hasException()) { log.error("retry exception", attempt.getExceptionCause()); } if (attempt.hasResult()) { if (attempt.getResult() == null) { log.info("retry return data is null"); } else { log.info("retry return data is:{}", JSON.toJSONString(attempt.getResult())); } } } }