消息队列:你要梭哈?

1.开局梭哈

       闲来没事写个农副产品信息发布系统,练手?那就多加点功能吧!MySQL、MyBatis-plus、Redis想到啥用啥,冲呀!!。。。。上线一看,好简陋........要不加个点赞系统?再加个购买积分系统?.....左100ms右100ms这不就是到我展示技术的时候了!

拿着如意金箍棒,我又想再来点推荐点相关信息,ok问题不大,执行流程再加100ms浏览历史检索相关商品信息。

反正加都加了要不再加个短信发送吧,用户下单完成后还能给发个短信提醒。

要不再加个?

      用户点开又是好一顿计算,这八十万数据谁爱算谁算,展示点数据费老鼻子劲,下个订单等了半天不带回复,到底成功没!点开主页也没显示。

      反正大体流程就是这样

      可以看到随着相关功能的增加,点击下单流程所涉及的系统不断增加,而作为主流的电商平台的程序处理压力也显而易见,平台越大相关的功能也就越多,但并没有出现所谓的反应卡顿之类的问题,但是按照前面的逻辑设计软件,用户买个东西发现花了十几秒才返回了相关信息,我可没有拼喜喜的实力,真香!(反应慢点怎么了!)。

2.项目优化

      之前做项目优化设计的时候,人家要求所有的接口的RtResponseTime响应时间)在200ms内,超出的全部优化。

      说到项目优化那就请出今天的主角消息队列————异步、削峰、解耦

异步:

      我们之前的场景里面有很多步骤都是在一个流程里面需要做完的,就比如说下单系统吧,本来我们业务简单,下单了付了钱就好,整个流程就走完了,但是随着项目需求的增加,单线程顺序处理服务所需的时间随之越来越长,用户体验也就随之越差。

既然处理速度慢,要如何优化呢? 

      现在又回到下单系统初始状态,它只需要确认下单完成(并确保订单信息的幂等性),然后直接返回订单成功信息,至于说后续的相关处理过程啥时候执行完成,对于用户的主观下单动作来说并没有关系,对于用户来说我已经点击下单你就要立即有相关的消息响应。

     既然单线程下的链式程序处理速度无法满足实际业务需求,那就该异步处理登场。

     那链路长了就慢了,但是我们发现上面的流程其实可以同时做的呀,你支付成功后,我去处理点赞的同时我可以去增减积分啊,还可以同时发个短信啊。

     那正常的流程我们是没办法实现的呀,怎么办,异步。

     你对比一下是不是发现,这样子最多只用100毫秒用户知道下单成功了,至于短信你迟几秒发给他他根本不在意是吧。

     如果是单纯的完成异步处理,也可以使用线程池,完全可以对开几个线程去完成异步。

    问题已经出现,那么就有请下一个主角。

解耦:

    你一个订单流程,你扣积分,扣优惠券,发短信,扣库存。。。等等这么多业务要调用这么多的接口,每次加一个你要调用一个接口然后还要重新发布系统,少了还好说,多的话......

   全部写到一块的话,不单单是程序间的耦合度高,问题排查的难度也更加麻烦,流程里面随便一个地方出问题搞不好会影响到其他的点,小伙伴说我每个流程都try catch不就行了,相信我别这么做,这样的代码就像个定时炸弹💣,你不知道什么时候爆炸,今天不炸明天炸!

但是你用了消息队列,耦合这个问题就迎刃而解了!

     你下单了,你就把你支付成功的消息告诉别的系统,他们收到了去处理就好了,你只用走完自己的流程,把自己的消息发出去,那后面要接入什么系统简单,直接订阅你发送的支付成功消息,你支付成功了我监听就好了。


     那你的流程走完了,你不用管别人是否成功么?比如你下单了积分没加,优惠券没扣怎么办?
问题是个好问题,但是没必要考虑,业务系统本身就是自己的开发人员维护的,你积分扣失败关我下单的什么事情?你管好自己下单系统的就好了。

     话是这样说,但是又引出消息队列对于消息可靠性发送所存在的问题(这里暂缺不谈)

削峰:

     就拿秒杀业务来说,你平时流量很低,但是你要做秒杀活动00 :00的时候流量疯狂怼进来,你的服务器,RedisMySQL各自的承受能力都不一样,你直接全部流量照单全收肯定有问题啊,直接就打挂了。

     既然用户有请求,也不能不接受,消息队列将对应的请求放到队列中,至于每秒处理多少,就是服务器的事了,但是至于谁处理多少,每台处理器的处理能力也不尽相同,这里就要提到负载均衡了,以RocketMQ为例,队列和消费者的消息处理就两种形式推,推的底层实现又是以拉为基础所以说能者多劳处理完了就拉取新的消息。

3.消息队列所存在的问题

系统复杂性

     本来蛮简单的一个系统,我代码随便写都没事,现在你凭空接入一个中间件在那,我是不是要考虑去维护他,而且使用的过程中是不是要考虑各种问题,比如消息重复消费消息丢失消息的顺序消费等等,反正用了之后就是贼烦。

数据一致性

    这个其实是分布式服务本身就存在的一个问题,不仅仅是消息队列的问题,但是放在这里说是因为用了消息队列这个问题会暴露得比较严重一点。

    就像我开头说的,你下单的服务自己保证自己的逻辑成功处理了,你成功发了消息,但是点赞系统,积分系统等等这么多系统,他们成功还是失败你就不管了?


所有的服务都成功才能算这一次下单是成功的,那怎么才能保证数据一致性呢?

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

可用性

你搞个系统本身没啥问题,你现在突然接入一个中间件在那放着,万一挂了怎么办?我下个单MQ挂了,优惠券不扣了,积分不减了,这不是杀一个程序员能搞定的吧,感觉得杀一片。

技术选型

目前在市面上比较主流的消息队列中间件主要有,Kafka、ActiveMQ、RabbitMQ、RocketMQ 等这几种。

我想说的是,ActiveMQ和RabbitMQ这两着因为吞吐量还有GitHub的社区活跃度的原因,在各大互联网公司都已经基本上绝迹了,业务体量一般的公司会是有在用的,但是越来越多的公司更青睐RocketMQ这样的消息中间件了。

Kafka和RocketMQ一直在各自擅长的领域发光发亮,

我这里用网上找的对比图让大家看看差距到底在哪里:


大家其实一下子就能看到差距了,就拿吞吐量来说,早期比较活跃的ActiveMQ 和RabbitMQ基本上不是后两者的对手了,在现在这样大数据的年代吞吐量是真的很重要。

比如现在突然爆发了一个超级热点新闻,你的APP注册用户高达亿数,你要想办法第一时间把突发全部推送到每个人手上,你没有大吞吐量的消息队列中间件用啥去推?

再说这些用户大量涌进来看了你的新闻产生了一系列的附带流量,你怎么应对这些数据,很多场景离开消息队列基本上难以为继。

就部署方式而言前两者也是大不如后面两个天然分布式架构的哥哥,都是高可用的分布式架构,而且数据多个副本的数据也能做到0丢失。

我们再聊一下RabbitMQ这个中间件其实还行,但是这玩意开发语言居然是erlang,我敢说绝大部分工程师肯定不会为了一个中间件去刻意学习一门语言的,开发维护成本你想都想不到,出个问题查都查半天。

至于RocketMQ(阿里开源的),git活跃度还可以。基本上你push了自己的bug确认了有问题都有阿里大佬跟你试试解答并修复的,

Kafka我放到最后说,你们也应该知道了,压轴的这是个大哥,大数据领域,公司的日志采集,实时计算等场景,都离不开他的身影,他基本上算得上是世界范围级别的消息队列标杆了。

以上这些都只是一些我自己的个人意见,真正的选型还是要去深入研究的,不然那你公司一天UV就1000你告诉我你要去用Kafka我只能说你吃饱撑的。

记住,没有最好的技术,只有最适合的技术,不要为了用而用。
 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值