👏大家好!我是和风coding,希望我的文章能给你带来帮助!
🔥如果感觉博主的文章还不错的话,请👍三连支持👍一下博主哦
📝点击 我的主页 还可以看到和风的其他内容噢,更多内容等你来探索!
📕欢迎参观我的个人网站:Gentlewind
什么是消息队列
消息队列:一般我们会简称它为MQ(Message Queue),消息队列中间件。他常常用来异步操作,解耦以及/削峰填谷。
但是他的本质实际上是异步的双端通讯
。
相比 Dubbo,http 协议等远程调用的方式,都是基于同步的请求-响应模式
,即客户端向服务器发送器发送一个请求,服务器处理请求并返回响应。在这个过程中,客户端会一直等待服务器的响应才会进行下一步操作。
而 MQ 就可以无视复杂的底层通讯协议,通过定义消费者和生产者两个对象构建了一个更高效的通讯模型。
消息队列的优点
消息队列有三大优点:
- 异步处理
- 削峰填谷
- 服务解耦
异步处理
比如在淘宝中用户发起订单,将消息发送至消息队列后就可以直接返回了。然后系统就会在后台调用以下的服务,这些服务都是异步同时进行的。
这样做的好处是:
- 提高系统的吞吐量和资源利用率:几个服务可以同时进行处理
- 提高用户体验:发送消息后就可以立即返回,减少了响应时间,用户无需在订单页面等待
- 便于扩展:后续需要增加服务非常方便(比如物流系统等),无需改动订单系统的代码,直接将物流系统连接到消息队列即可,减少了代码的耦合。
流量控制
一般情况下我们服务器的负载能力都是固定的。比如能够支撑几万的 qps,而当有类似于淘宝的秒杀服务,或者某个时间段用户的操作变多,那么这些请求直接打到服务器就容易压垮服务器。
但是有了消息队列,客户端可以将请求发送到消息队列中,因为消息队列是不需要处理业务逻辑的,所以支撑的并发量可以是百万级的。这样可以在并发量高时减小服务器压力,在并发量小时继续消费消息。后台始终保持着较平衡的负载。
我们可以总结为“削峰填谷”,可以类比大坝,水龙头等对流量进行拦截,并按需进行处理
服务解耦
可以将服务之间进行解耦,订单系统只需要将消息发送到消息队列,而其他服务只需要各自从消息队列中拿到消息进行处理。当中如果有一个服务发生宕机或者网络延迟,都不影响其他服务的使用,提高系统的高可用性。(后续可以通过分布式事务来保证数据的一致性)
消息队列的缺点
提高了系统的复杂性
如果说业务量不大,并发也不高,就没必要使用消息队列。
导致数据的一致性问题
消息队列的引入也会导致数据传输时的一致性问题。在分布式系统中,如果两个节点之间存在数据同步,就会带来数据一致性的问题。
解决办法可以参考事务问题:
第一种就是采用分布式事务,将下单这个操作里涉及的所有服务放到一个事务里面,要么都成功,要么都失败。
第二种就是消费者各自做好合理的数据补偿措施,比如说消息重试,人工刷数据等等
可用性
刚才讲了解耦,其实是系统的各个模块之间的解耦,但是这些模块都和消息队列关联,万一消息队列挂了,就真的下不了单了。为了保证可用性,我们可以采用消息队列集群,负载均衡,前端流量限流等