什么是消息队列(MQ)
我们可以把消息队列比作是一个存放消息的容器,当我们需要使用消息的时候可以取出消息供自己使用。消息队列是分布式系统中重要的组件,使用消息队列主要是为了通过异步处理提高系统性能和削峰、降低系统耦合性。
说白了,MQ就是一个消息中间件,它在消息发送上游和消息接收下游之间,使用了MQ之后,消息的上下游之间就实现了解耦,上游消息的发送处理是通过MQ来实现的,而不是下游其他服务。
MQ的大体工作流程
MQ把要传输的数据(消息)放在队列中,用队列机制来实现消息传递——生产者产生消息并把消息放入队列,然后由消费者去处理。消费者可以到指定队列拉取消息,或者订阅相应的队列,由MQ服务端给其推送消息。
MQ的用处
消息队列中间件是分布式系统中重要的组件,主要解决应用解耦,异步消息,流量削锋等问题,实现高性能,高可用,可伸缩和最终一致性架构。
MQ最主要的两个特点就是异步和解耦
(1) 通过异步处理提高系统性能(削峰、减少响应所需时间)
在一些处理时间较长,且发送方对处理方的处理结果不是必须时,我们使用MQ就能很好地提升我们的这个响应速度。比如一些非关键数据插入数据库的操作,我们就可以异步给MQ进行插入。
比如,我们发帖子,我们最主要的是关注贴子是否发布成功,而对于关注发帖人的用户进行通知不是最重要的,我们不需要等到通知完所有关注人有新贴子才结束处理,而是可以在发帖成功之后发一个通知消息进mq,然后直接通知发帖人发帖成功,而通知的处理由mq异步处理。
我们还可以用MQ实现削峰的作用,在一些并发量较大的情况时,我们可以将短时间内产生的事务存储在消息队列中,从而减缓对业务系统的压力。
比如一些电商的促销活动,我们在用户请求之后,将消息写入队列之后返回给用户一个提示(比如订单已提交等),不能直接返回成功,因为可能会存在处理失败的情况,在队列真正处理完订单后,我们再将订单修改状态或者通知用户订单成功。
(2) 降低系统耦合性
使用了MQ之后,消息发送方和消息处理方不存在直接调用的关系,所以消息发送方和消息处理方之间的耦合性就较小了,当我们修改或者新增发送和处理模块时,对其他模块的影响就较小了,一般我们只需要修改mq的处理逻辑即可,这样我们的扩展性也较好。
比如一个电商应用,如果把订单系统、库存系统、物流系统、支付系统都耦合在一起,那么任何一个系统出了故障,都会造成下单操作异常,无法下单。当转变成基于消息队列的方式后,系统间调用的问题会减少很多,比如物流系统因为发生故障而发货失败了,那么需要几分钟来修复。在这几分钟的时间里,物流系统要处理的订单消息会被缓存在消息队列中,用户的下单操作依旧是可以正常完成的。
MQ的不足
1、系统更复杂,多了一个MQ组件,需要考虑消息丢失、消息重复消费、消息传递的顺序性等问题。
2、消息传递路径更长,延时会增加
3、消息可靠性和重复性互为矛盾,消息不丢不重难以同时保证。使用消息队列,我们就要考虑如何保证消息不被重复消费?如何保证消息的可靠地传输,不丢失消息?需要考虑主业务和从属业务一致性的处理。
4、上游无法知道下游的执行结果
5、系统可用性降低。依赖服务也多,服务越容易挂掉。需要考虑MQ瘫痪的情况。
注:调用方实时依赖执行结果的业务场景,使用调用,而不是MQ。例如:登录,必须登录校验完成后,才能让用户进入页面,而不是使用MQ异步校验。
主流的MQ产品
现在主流的MQ产品包括:RabbitMQ、RocketMQ、、Kafka 等。