阿里妈妈再也不用担心异步任务失败后没人知晓了

springboot异步异常全局处理

很多异步的场景可以提升不少系统的性能 ,但是不可避免的异步会产生报错,报错怎么处理呢,平常的做法是将异步的代码块做try catch操作,但是未免会有一些人会忘记写这个,并且每个方法里都写上这个会不会显得代码太臃肿。springboot提供了我们全局处理业务异常的方法,当然也有全局异步异常处理的方法。下面看看如何配置异步的全局异常

首先写个config,代码如下:

@Slf4j
@Configuration
public class AsyncExceptionConfig implements AsyncConfigurer {

  @Override
  public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
    return new SpringAsyncExceptionHandler();
  }

  class SpringAsyncExceptionHandler implements AsyncUncaughtExceptionHandler {
    @Override
    public void handleUncaughtException(Throwable throwable, Method method, Object... objects) {
      log.error("异步任务错误,method:{}, throwable:{}, param:{}", method, throwable, objects);
    }
  }
}

接下来我们写个测试代码,来测试有效性

写个Controller

@Slf4j
@RestController
@RequestMapping(value = "test")
public class TestAsyncController {

  @Autowired
  private TestService testService;

  @GetMapping(value = "/yy/{name}")
  public void test111(@PathVariable("name") String name){
    log.info("开始测试,{}", name);
    testService.test(name);
    log.info("结束测试,{}", name);
  }
}

再写个service,因为spring的异步调用是通过动态代理实现的,所以需要通过类的外部调用来调用异步的方法,代码如下:

@Slf4j
@Service("testService")
public class TestService {

  @Async
  public void test(String name){
    log.info("异步方法。。。。。。。。。。。{}", name);
    throw new BusinessRuntimeException("测试异步异常,参数:"+ name);
  }
}

测试代码到这里就写完了。我们启动服务做个测试,需要注意的一点是使用@Async必须在类外部调用,类内部调用不会走springboot的动态代理,也就不会是异步的操作。

2020-04-21 15:58:47.293  INFO 19476    - 开始测试,zhangsan
2020-04-21 15:58:47.299  INFO 19476    - 结束测试,zhangsan
2020-04-21 15:58:47.314  INFO 19476    - 调用[/test/yy/zhangsan]耗时:100
2020-04-21 15:58:47.327 DEBUG 19476    - headerVer:
2020-04-21 15:58:47.336  INFO 19476    - 异步方法。。。。。。。。。。。zhangsan
2020-04-21 15:58:47.338 ERROR 19476    - 异步任务错误,method:public void com.xxx.xxx.xxx.controller.TestService.test(java.lang.String), throwable:com.xxx.xxx..BusinessRuntimeException: 测试异步异常,参数:{}zhangsan, param:[zhangsan]

可以看到异常被捕获了,并且method中打印出了详细的类及方法名,参数类型,异常类型,及参数内容。

看到这里是不是就有小伙伴突发奇想,异步操作失败重试。获取上下文中的bean,调用对应的方法,并传递参数应该不难吧。

失败的方法继续重试有可能继续失败,总不能一直重试吧,对CPU是极大的消耗,所以一定要设置重试次数,超过上限后,失败的任务怎么办呢,当然最友好的方法是让开发知道,这里报错了,所以可以继续使用logback的发邮件的机制,将失败超过一定次数的异步任务错误信息提交给相关开发人员。做对应的弥补措施。

下一篇就要分享一下logback如何配置发送邮件给对相应的人。欢迎大家关注

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值