什么是消息队列
消息队列,又叫做Message Queue,所以又简称为MQ。MQ是一种进程间通信或同一进程的不同线程间的通信方式,直白的说就是存放消息的队列。常用的消息队列有RabbitMQ、RocketMQ、ActiveMQ、Kafka、ZeroMQ、MetaMq等,而使用Redis和MySQL也可以实现消息队列。
什么时候需要用消息队列(使用场景)
先来看看消息队列的特点(优点)吧:
- 应用耦合:多应用间通过消息队列对同一消息进行处理,避免调用接口失败导致整个过程失败;
- 异步处理:多应用对消息队列中同一消息进行处理,应用间并发处理消息,相比串行处理,减少处理时间;
- 限流削峰:广泛应用于秒杀或抢购活动中,避免流量过大导致应用系统挂掉的情况;
- 消息驱动的系统:系统分为消息队列、消息生产者、消息消费者,生产者负责产生消息,消费者(可能有多个)负责对消息进行处理;
简单来说就是当不需要立即获得结果,但是并发量又需要进行控制的时候,差不多就是需要使用消息队列的时候了。
应用耦合
有这么个场景,用户使用相册上传一张图片或者现拍一张照片,人脸识别系统会对该图片进行人脸识别,一般的做法是,服务器接收到图片后,图片上传系统立即调用人脸识别系统,调用完成后再返回成功
这样存在几个缺点:
- 人脸识别系统被调失败,导致图片上传失败;
- 延迟高,需要人脸识别系统处理完成后,再返回给客户端,即使用户并不需要立即知道结果;
- 图片上传系统与人脸识别系统之间互相调用,需要做耦合;
若使用消息队列:
客户端上传图片后,图片上传系统将图片信息写入消息队列,直接返回成功;而人脸识别系统则定时从消息队列中取数据,完成对新增图片的识别。此时图片上传系统并不需要关心人脸识别系统是否对这些图片信息的处理、以及何时对这些图片信息进行处理。
异步处理
在我们日常的业务开发中,随着业务的增长,涉及的业务也会越来越复杂,比如从最初的购买一个商品,以前是下单就到支付然后就结束了,但随着业务的增长,可能会增加比如优惠券、短信等。
这时候我们有两种处理方式,分别是串行和并行方式。
串行方式:用户下单后调用支付,接着使用优惠券,最后发送短信,然后返回结果给客户端,这种方式必须得发送短信后才返回结果给客户端。
并行方式:用户下单后调用支付后,使用优惠券和发送短信并行处理,这种情况下是处理完返回结果给客户端。
使用消息队列:用户下单调用支付后发送消息给消息队列后立刻返回结果给客户端,至于短信和优惠券在接收到消息后自行执行就好,大大提高了响应速度。
但大家应该也会好奇,流程走完了,你不管短信和优惠券的执行成功还是失败么,比如优惠券使用失败、短信发送失败怎么办,这个确实是问题,但业务本身就是开发人员维护的,短信发送失败、优惠券使用失败关我下单什么事?虽然这样说,但同样有解决方法,在这篇就不过多赘述了。
限流削峰
有这么一个场景,某个购物网站开展秒杀活动,一般由于瞬时访问量过大,服务器接收过大,会导致流量暴增,相关系统无法处理请求甚至崩溃。而加入消息队列后,系统可以从消息队列中取数据,相当于消息队列做了一次缓冲。
优点:
- 请求先入消息队列,而不是由业务处理系统直接处理,做了一次缓冲,极大地减少了业务处理系统的压力;
- 队列长度可以做限制,事实上,秒杀时,后入队列的用户无法秒杀到商品,这些请求可以直接被抛弃,返回活动已结束或商品已售完信息;
消息驱动的系统
假如有这么一个场景,用户新上传了一批照片, 人脸识别系统需要对这个用户的所有照片进行聚类,聚类完成后由对账系统重新生成用户的人脸识别。这三个子系统间由消息队列连接起来,前一个阶段的处理结果放入队列中,后一个阶段从队列中获取消息继续处理。
优点:
- 避免了直接调用下一个系统导致当前系统失败;
- 每个子系统对于消息的处理方式可以更为灵活,可以选择收到消息时就处理,可以选择定时处理,也可以划分时间段按不同处理速度处理;
总结
本文基本描述了何为消息队列和消息队列的特点,大部分提及了消息队列的优点,但每一项技术都是有两面性的,消息队列同样有缺点,需要我们通过一定的手段去解决,后面我将会继续对于缺点的解决以及几大中间件(消息队列)进行叙述。
文章评论
胜哥tql
@水军2号 胜哥yyds
我滴偶像!!!!!!!!!!!!!!!