什么是消息队列
学一个东西或者技术,首先要知道他是什么,为什么要学他,如何学?在此我分享一下我的经验。
先来看一下消息队列的英文解释:
In computer science, message queues and mailboxes are software-engineering components typically used for inter-process communication (IPC), or for inter-thread communication within the same process. They use a queue for messaging – the passing of control or of content. Group communication systems provide similar kinds of functionality.
翻译一下:在计算机科学领域,消息队列和邮箱都是软件工程组件,通常用于进程间或同一进程内的线程通信。它们通过队列来传递消息-传递控制信息或内容,群组通信系统提供类似的功能。
简单来说:就是使用一个队列,来保持通信的。是一个中间件。
为什么要用消息队列
举个例子,这是我调用AI接口的代码片段。具体流程这样(采用自定义线程池来实现):
1、用户从前端传入文件,请求AI进行分析。
2、后端拿到文件调用AI接口进行分析。
但是有个问题,AI分析是需要时间的,如果是同步执行,那么用户的体验不是很好,需要一直等待。我们选择用线程池实现,这样就实现了异步。
// 调用线程池
CompletableFuture.runAsync(() ->{
// 将状态改为running
handleChartStatusRunning(chartID);
// 调用AI
String result = aiManager.product(biModelId, userInput.toString());
String[] splits = result.split("····");
if (splits.length < 3) {
throw new BusinessException(ErrorCode.SYSTEM_ERROR, "AI 生成错误");
}
String genChart = splits[1].trim();
String genResult = splits[2].trim();
// 将状态改为成功
handleChartStatusSucceed(chartID,genChart,genResult);
},threadPoolExecutor);
BiResponse biResponse = new BiResponse();
biResponse.setChartId(chartID);
return biResponse;
}
但是这样还是会存在问题的,假如AI最多只能供2个用户使用,单机服务核心线程数最大设置2,这样单体应用是没问题的,但现在,微服务架构,成百上千的服务之间相互调用,分布式,有N台服务器,如果这样做,每个服务器都会有线程池,2N个线程,会导致崩溃。所以只能单机限制,无法集中限制,那么什么能解决呢?
没错,消息队列就应运而生了。它常用来实现:异步处理、服务解耦、流量控制。
异步处理
随着公司的发展你可能会发现你项目的请求链路越来越长,例如刚开始的电商项目,可以就是粗暴的扣库存、下单。慢慢地又加上积分服务、短信服务等。这一路同步调用下来客户可能等急了,这时候就是消息队列登场的好时机。
调用链路长、响应就慢了,并且相对于扣库存和下单,积分和短信没必要这么的 “及时”。因此只需要在下单结束那个流程,扔个消息到消息队列中就可以直接返回响应了。而且积分服务和短信服务可以并行的消费这条消息。
可以看出消息队列可以减少请求的等待,还能让服务异步并发处理,提升系统总体性能。
消息队列的作用
流量控制
在高并发场景下,达到削峰填谷作用,像一些例如秒杀活动爆发式流量打过来后端可能就顶不住了。因此需要引入一个中间件来做缓冲,消息队列再适合不过了。
网关的请求先放入消息队列中,后端服务尽自己最大能力去消息队列中消费请求。超时的请求可以直接返回错误。
当然还有一些服务特别是某些后台任务,不需要及时地响应,并且业务处理复杂且流程长,那么过来的请求先放入消息队列中,后端服务按照自己的节奏处理。这也是很 nice 的。
消息队列都能在其中发挥很好的缓冲效果。
强稳定性
比如金融服务,这种一定不能错的服务,可以引入消息队列来进行保证,持久化,可靠性。
消息队列的缺点
- 引入额外的中间件,系统会更复杂,增加额外的成本。
- 数据的一致性,消息丢失。
主流的分布式队列选型
公司的话Kafka用的比较多,RabbitMQ生态好,易于理解,可扩展性不错,适用于中小型的项目,我们下一篇将教你学习RabbitMQ。