数据库学习笔记:消息队列

消息队列在互联网技术存储方面使用如此广泛,几乎所有的后端技术面试官都要在消息队列的使用和原理问上一问。

为啥用消息队列

一开始业务体量小,可以通过单机一把梭就搞定,而后业务体量不断扩大,转为采用微服务的设计思想和分布式的部署方式,拆分了服务。单机的技术栈与中间件对于大体量和复杂大的业务场景就不够用了,对系统的友好性下降,通过技术选型,决定的引入消息队列中间件

什么场景用到消息队列

消息队列的三个经典应用场景:异步、削峰、解耦

异步:

就比如说下单系统吧,单纯的下单系统业务简单,下单了付了钱就好了,流程就走完了。如果加上优惠券系统(100ms去扣减优惠券积分系统(200ms去增减积分),短信提醒(100ms去发个短信)。反正就流程有点像这样 ↓

但复杂的下单系统远不于此,绝对在10个以上(主流电商),越大的越多。这个链路这样下去,时间长得一批,用户发现买个东西要花几十秒,用户体验极差,那只能优化系统了。

Tip:某电商要求所有接口的RtResponseTime响应时间)在200ms内,超出的全部优化,如果系统QPS(每秒查询率)是9W+(就是抖动一下网络集群都可能炸锅那种RT基本上都要求在50ms以内。

怎么解决

可以同时做,支付成功后,校验优惠券的同时可以去增减积分,还可以同时发个短信。通过异步。对比一下就发现,这样最多只用100毫秒用户知道下单成功了,至于短信你迟几秒发给他根本不是重点。

异步,为何不用线程,线程池

解耦:

用线程去做,不仅要写代码,而且一个订单流程,扣积分,扣优惠券,发短信,扣库存等等这么多业务要调用这么多的接口,每次加一个就要调用一个接口然后还要重新发布系统,真的全部都写在一起的话,不单单是耦合这一个问题,出问题排查也麻烦,流程里面随便一个地方出问题搞不好会影响到其他的点,而如果使用 try catch的代码会像个定时炸弹💣,你不知道什么时候爆炸,平时不炸做活动的时候也会炸的,引发P0故障(P0—PN 是互联网大厂经常用来判定事故等级的机制,P0是最高等级了。)但是用了消息队列,耦合这个问题就迎刃而解了。

下单了,就把支付成功的消息告诉别的系统,当前系统只用走完自己的流程,把自己的消息发出去,即使后面要增加接入系统,可以直接订阅发送的支付成功消息,让追加的系统监听就可以了

如果下单了积分没加,优惠券没扣怎么办?

问题其实对于下单系统来说没必要考虑,业务系统本身就是自己的开发人员维护的,积分扣失败不关下单的事情,各自管好自己系统的就好了。但是这其实是消息队列的一个缺点,涉及到分布式事务(数据一致性的问题)

削峰:

比如秒杀,平时流量很低,但是做秒杀活动00 :00的时候流量疯狂怼进来,服务器,RedisMySQL各自的承受能力都不一样,直接全部流量照单全收肯定有问题啊,直接就打挂了。把请求放到队列里面,然后至于每秒消费多少请求,就看自己的服务器处理能力,假如能处理5000QPS那就消费这么多,可能会比正常的慢一点,但是不至于打挂服务器,等流量高峰下去了,服务也就没压力了。比如阿里双十一12:00的时候这么多流量瞬间涌进去,他有时候也会慢一点,但是也人家没挂,或者可以降级给个友好的提示页面,等高峰过去了就好了。

消息队列的缺点

技术是把双刃剑!也从三个点介绍主要的缺点:

系统复杂性

增加接入这么一个中间件在那,就要考虑去维护它,而且使用的过程中要考虑各种问题,比如消息重复消费消息丢失消息的顺序消费(之后介绍)等等。

数据一致性

这个其实是分布式服务本身就存在的一个问题,不仅仅是消息队列的问题,但是用了消息队列这个问题会暴露得比较严重一点。比如下单的服务自己保证自己的逻辑成功处理了,成功发了消息,但是优惠券系统,积分系统等等这么多系统,我说了保证自己的业务数据对的就好了。所有的服务都成功才能算这一次下单是成功的,那怎么才能保证数据一致性呢?

分布式事务:把下单,优惠券,积分。。。都放在一个事务里面一样,要成功一起成功,要失败一起失败。

可用性

比如万一MQ挂了怎么办?优惠券不扣了,积分不减了。这就是保证高可用的问题了,

MQ的技术选型

目前在市面上比较主流的消息队列中间件主要有,Kafka、ActiveMQ、RabbitMQ、RocketMQ 等这几种。不过ActiveMQRabbitMQ这两者因为吞吐量还有GitHub的社区活跃度的原因,在各大互联网公司都已经基本上绝迹了,业务体量一般的公司会是有在用的,但是越来越多的公司更青睐RocketMQ这样的消息中间件了。KafkaRocketMQ一直在各自擅长的领域发光发亮,部分比如蚂蚁金服,字节跳动和美团,用的都有点不一样,应该都是各自的中间件,可能做过修改,也可能是自研的,大多没有开源。有些公司就是是基于KafkaRocketMQ两者的优点自研的消息队列中间件,吞吐量、可靠性、时效性等都很可观。

至于这四种消息队列中间件对比如下:

就拿吞吐量来说,早期比较活跃的ActiveMQ 和RabbitMQ基本上不是后两者的对手了,在现在这样大数据的年代吞吐量是真的很重要。比如现在突然爆发了一个超级热点新闻,APP注册用户高达亿数,你要想办法第一时间把突发全部推送到每个人手上,你没有大吞吐量的消息队列中间件很难实现,再说这些用户大量涌进来看了你的新闻产生了一系列的附带流量,你怎么应对这些数据,很多场景离开消息队列基本上难以为继。就部署方式而言前两者也是大不如后面两个天然分布式架构,都是高可用的分布式架构,而且数据多个副本的数据也能做到0丢失。RabbitMQ这个中间件其实还行,但是开发语言居然是erlang,绝大部分工程师肯定不会为了一个中间件去刻意学习一门语言的,开发维护成本太高。至于RocketMQ(阿里开源的),git活跃度还可以。架构设计部分跟同样是阿里开源的一个RPC框架是真的很像(Dubbo)。

Kafka压轴,大数据领域,公司的日志采集,实时计算等场景,都离不开它的身影,它基本上算得上是世界范围级别的消息队列标杆了。以上这些都只是一些自己的个人意见,真正的选型还是要去深入研究的,不然一天UV就1000要去用Kafka。记住,没有最好的技术,只有最适合的技术,不要为了用而用

总结

消息队列的基础知识就先这么多,消息队列在面试里面基本上也是跟Redis一样必问的。面试的思路:要知其然,也要知其所以然,就是要知道为啥用,用了有啥好处,有啥坑。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

薛定谔的猫96

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值