SpringRetry异常重试

阅读: 评论:0

SpringRetry异常重试

SpringRetry异常重试

SpringRetry

  • 介绍:
  • pom引入
  • 启动类上加注解
  • 需要重试的方法上加@Retryable
  • 代码示例

介绍:

  • spring retry是从spring batch独立出来的一个能功能,主要实现了重试和熔断。当某一次网络请求失败时,能够重新进行尝试请求,解决某一时间的网络问题导致整个请求失败。
  • 常见应用场景:
    • (1)微服务之间的feign接口retry
    • (2)微服务与第三方服务之间API对接的retry
    • (3)服务与database之间的retry

pom引入

        <dependency><artifactId>spring-retry</artifactId><groupId></groupId><version>${version}</version></dependency>
--  版本号
&version>1.2.5.RELEASE</version>

启动类上加注解

// 启动Retry
@EnableRetry
// 启用异步 因为我使用的是异步的模式 
@EnableAsync

需要重试的方法上加@Retryable

    // 基础写法, 但是 生产肯定要抽取到配置文件中@Retryable(value= {BusinessException.class},maxAttempts = 5,backoff = @Backoff(delay = 5000l,multiplier = 1))// 抽取到配置文件写@Retryable(value = BusinessException.class, maxAttemptsExpression = "${retry.attempts}", backoff = @Backoff(delayExpression = "${retry.delay}", multiplierExpression = "${retry.multiplier}"))//配置文件
retry:# 重试次数attempts: 3# 重试延迟时间delay: 1000# 重试延迟倍率multiplier: 0
#参数解释:
@Retryable 标注此注解的方法在发生异常时会进行重试value:指定处理的异常类include:指定处理的异常类和value一样,默认为空,当exclude也为空时,默认所有异常exclude:指定异常不处理,默认空,当include也为空时,默认所有异常maxAttempts:最大重试次数。默认3次backoff: 重试等待策略。默认使用@Backoff注解@Backoff 重试等待策略不设置参数时,默认使用FixedBackOffPolicy(指定等待时间),重试等待1000ms设置delay,使用FixedBackOffPolicy(指定等待时间),重试等待填写的时间设置delay和maxDealy时,重试等待在这两个值之间均态分布设置delay、maxDealy、multiplier,使用 ExponentialBackOffPolicy(指数级重试间隔的实现 ),multiplier(指定延迟倍数)默认为0,表示固定暂停1秒后进行重试,如果把multiplier设置为1.5,则第一次重试为2秒,第二次为3秒,第三次为4.5秒。,比如delay=5000l,multiplier=2,则第一次重试为5秒,第二次为10秒,第三次为20秒
……@Recover 用于@Retryable重试失败后处理方法,此注解注释的方法参数一定要是@Retryable抛出的异常,否则无法识别,可以在该方法中进行日志处理。注: 
1.当同步的时候代码执行完重试方法会继续执行.所以异步的后续逻辑要写到重试方法里面,比如发送结果的处理.
2.由于Spring Retry是采用AOP实现的重试机制,需要避免方法内部调用,会使aspect增强失效

代码示例

slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import annotation.Backoff;
import annotation.Recover;
import annotation.Retryable;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;/*** @version 1.0  发送 重试实现类* @description: ReceiveBackRetryService* @author: 单人影* @create: 2021-06-28 09:52**/
@Service
@Slf4j
public class SendMsgLogic {@Value("${retry.attempts}")private int retryTimes;@Value("${fdepUrl}")private String fdepUrl;@Value("${encryFlag}")private String encryFlag;@Value("${spring.application.name}")private String appName;/*** @description: 异步发送* @param: [msg804BO]* @return: void* @author: 单人影* @date: 2021/6/28 10:13* @version: 1.0*/@Retryable(value = BusinessException.class, maxAttemptsExpression = "${retry.attempts}", backoff = @Backoff(delayExpression = "${retry.delay}", multiplierExpression = "${retry.multiplier}"))@Asyncpublic void send(BcmTrustSendMsgFlowDO flowDO, RetryTransferBO retryTransferBO) {log.info("发送消息编号:{}.重试信息:{}", MsgNo(), JacksonUtils.objectToString(retryTransferBO));//1.feign 调用 发送信息String sendMessage;if (Code().equals(encryFlag)) {sendMessage = MsgContent());} else {sendMessage = MsgContent();}SendMessageRequest sendMessageRequest = new SendMessageRequest();sendMessageRequest.setMessage(sendMessage);sendMessageRequest.setAppName(appName);log.info("发送fdep信息,请求地址:{},请求参数:{}", fdepUrl, JacksonUtils.objectToString(sendMessageRequest));// feign异步调用Result voidResult = FdepSendApiUtil.sendByHttp(fdepUrl, sendMessageRequest);log.info("发送信息请求参数:{},响应结果:{}", sendMessage, JacksonUtils.objectToString(voidResult));if (Count() == null) {retryTransferBO.setCount(0);}retryTransferBO.Count() + 1);retryTransferBO.setResult(voidResult);if (ResultUtils.checkVoidFail(voidResult)) {// 重试日志("发送报文请求失败,请求参数:{},响应结果:{}", JacksonUtils.objectToString(flowDO),JacksonUtils.objectToString(voidResult));throw new BusinessException(ErrorEnums.BCM05039999);} else {// 发送成功处理逻辑if (RetryTimes() != null) {flowDO.RetryTimes() + 1);}flowDO.setSendStatus(Code());flowDO.setSendTime(DateUtils.sysdateTo5());bcmTrustSendMsgFlowLogic.updateById(flowDO);if (Code().IntNum())) {log.info("发送消息回执成功,处理原订单回执状态:{}", MsgContent());Msg804BO msg804BO = JacksonUtils.MsgContent(), Msg804BO.class);BcmTrustReceiveMsgFlowDO oneByMsgNo = ReturnMsgNo());if (oneByMsgNo == null) {//原消息未通过校验 就不会落库log.warn("根据回执流水号查询原消息失败:{}", ReturnMsgNo());} else {log.info("根据消息id:{}.原消息状态:{}", Id(), ReturnStatus());oneByMsgNo.setReturnStatus(Code());bcmTrustReceiveMsgFlowLogic.updateById(oneByMsgNo);}}}log.info("发送消息编号:{} 结束", MsgNo());}@Recoverpublic RetryTransferBO recover(BusinessException exception, BcmTrustSendMsgFlowDO sendMsgFlowDO,RetryTransferBO retryTransferBO) {//回调  发送回执失败("发送消息失败:{}", JacksonUtils.objectToString(sendMsgFlowDO));sendMsgFlowDO.setRetryTimes(retryTimes);sendMsgFlowDO.setSendStatus(Code());bcmTrustSendMsgFlowLogic.updateById(sendMsgFlowDO);
//发送失败报警信息alertMessageLogic.sendFail(sendMsgFlowDO);return retryTransferBO;}
}
import java.io.Serializable;
import lombok.Data;/*** @description: RetryTransferBO 类只是我 为了记录当前是第几次重试,每次重试的信息结果* @author: 单人影* @date: 2021/6/28 13:14* @version: 1.0*/
@Data
public class RetryTransferBO implements Serializable {private static final long serialVersionUID = -1772838344464666024L;/*** 重试次数*/private Integer count;/*** feign请求返回类*/private Result result;/*** feign返回检查 是否成功** @return*/public boolean checkFailResult() {return result == null || IsSuccess() == null || !IsSuccess();}
}

本文发布于:2024-02-02 23:04:47,感谢您对本站的认可!

本文链接:https://www.4u4v.net/it/170688628647040.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:重试   异常   SpringRetry
留言与评论(共有 0 条评论)
   
验证码:

Copyright ©2019-2022 Comsenz Inc.Powered by ©

网站地图1 网站地图2 网站地图3 网站地图4 网站地图5 网站地图6 网站地图7 网站地图8 网站地图9 网站地图10 网站地图11 网站地图12 网站地图13 网站地图14 网站地图15 网站地图16 网站地图17 网站地图18 网站地图19 网站地图20 网站地图21 网站地图22/a> 网站地图23