1.异步任务
1.1.概述
举一个例子,我现在有一个网上商城,客户在界面点击下单后,后台需要完成两步:
1.创建客户订单
2.发短信通知客户订单号
这里面第2步是个高耗时的操作,如果全部挤在一条主线程里做,效果就会是客户点了一下界面的下单按钮,然后转半天圈,直到客户收到短信后,界面才停止转圈。
这里面我们发现其实我们并不需要等第2步完全跑完再返回,只要调用触发低2步就可以返回了。
第2步很适合做成异步任务,只要触发了就行,快速给出响应,不让请求卡在接口上,不必等它完整做完。
1.2.使用
spring提供了一个AsyncConfigurer接口,用来支持我们自定义一个线程池作为异步任务的线程池。
1.AsyncConfigurer接口:
package org.springframework.scheduling.annotation; import java.util.concurrent.Executor; import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler; import org.springframework.lang.Nullable; public interface AsyncConfigurer { //获取线程池 @Nullable default Executor getAsyncExecutor() { return null; } //异步异常处理器 @Nullable default AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() { return null; } }
2.自定义一个异步线程池:
@Configuration @EnableAsync //开启Spring对异步的支持 public class AsyncConfig implements AsyncConfigurer { @Override public Executor getAsyncExecutor() { //定义线程池 ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor(); //核心线程数 taskExecutor.setCorePoolSize(10); //线程池最大线程数 taskExecutor.setMaxPoolSize(30); //线程队列最大线程数 taskExecutor.setQueueCapacity(2000); //初始化 taskExecutor.initialize(); return taskExecutor; } }
3.使用异步任务:
用@Async注解的方法会交给自定义的异步线程池来执行。
@Async注解的接口只要将任务交给线程池里面的线程后就会快速返回响应,而不会等方法执行完。
import org.springframework.scheduling.annotation.Async; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class TestController { @RequestMapping("test") @Async public void test(){ try { Thread.sleep(10000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName()); } }
2.异步消息
2.1.概述
有时候,点对点的消息传送可能出现消费能力跟不上生产能力导致数据积压的情况出现,这时候异步消息就派上了用场。
以1.1章节中举例的场景为例,发短信的线程和客户之间就是点对点的,只要订单下得够快,线程池很快还是会被打满:
这时候我们就需要将这种点对点的同步关系,通过MQ这个中间层解为异步的关系
2.2.使用
异步消息其实本质上就是将数据放到MQ中,以下是博主写的用Spring Boot操作rabbitMQ的文章,清晰易懂,可以参考,至于其它MQ的话,术有千法,道本归一:
SpringBoot RabbitMq 六大模式_springboot整合rabbitmq六种模式__BugMan的博客-CSDN博客

