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如何配置发送邮件给对相应的人。欢迎大家关注