【高并发】为何高并发系统中都要使用消息队列?这次彻底懂了!
许多高并发体系中都会运用到音讯行列中间件,那么,问题来了,为什么在高并发体系中都会运用到音讯行列中间件呢?立志成为资深架构师的你思考过这个问题吗?
本文集结了许多技术大牛的编程思维,由冰河会聚并整理而成,在此,感谢那些在技术发展道理上默默付出的长辈们!
场景剖析
现在假定这样一个场景,用户下单成功需要给用户发短信,假如没有音讯行列,咱们会挑选同步调用发短信的接口并等候短信发送成功。现在假定短信接口实现呈现了问题或许短信发送短时间内达到了上限,这个时分是挑选重试几次还是放弃发送呢?
这儿的规划会很杂乱。假如运用了音讯行列,咱们挑选将发短信的操作封装成一条音讯发送到音讯行列,音讯行列告诉一个服务去发送一条短信,即便呈现了上述的问题,可以挑选把音讯从头放到音讯行列里等候处理。
音讯行列的优点
经过上述了比如,咱们看到音讯行列完成了一个异步解耦的过程,短信发送时咱们只需确保短信发到音讯行列成功就可以了,接下来就可以去做其他工作;
其次,规划变得更简单,在下单的场景下,咱们不必过多考虑发送短信的问题,交给音讯行列办理就行了,或许短信发送会有推迟,可是确保了终究的一致性。
音讯行列特性
- 业务无关,只做音讯分发。
- FIFO,先投递先抵达。
- 容灾:节点动态增删和音讯耐久化。
- 性能:吞吐量进步,体系内部通讯功率进步。
高并发体系为何运用音讯行列?
(1)业务解耦
成功完成了一个异步解耦的过程。短信发送时只需确保放到音讯行列中就可以了,接着做后面的工作就行。一个业务只关怀本质的流程,需要依赖其他工作可是不那么重要的时分,有告诉即可,无需等候成果。每个成员不必受其他成员影响,可以更独立自主,只经过一个简单的容器来联系。
关于咱们的订单体系,订单终究付出成功之后或许需要给用户发送短信积分什么的,但其实这已经不是咱们体系的中心流程了。假如外部体系速度偏慢(比如短信网关速度不好),那么主流程的时间会加长许多,用户必定不希望点击付出过好几分钟才看到成果。那么咱们只需要告诉短信体系“咱们付出成功了”,不必定非要等候它处理完成。
(2)终究一致性
主要是用记载和补偿的方法来处理;在做一切的不确定工作之前,先把工作记载下来,然后去做不确定的事,它的成果一般分为三种:成功,失利或许不确定;假如成功,咱们就可以把记载的东西清理掉,关于失利和不确定,咱们可以选用守时使命的方法把一切失利的工作从头做一遍直到成功停止。
确保了终究一致性,经过在行列中存放使命确保它终究必定会执行。
终究一致性指的是两个体系的状况保持一致,要么都成功,要么都失利。当然有个时间限制,理论上越快越好,但实际上在各种反常的情况下,或许会有必定推迟达到终究一致状况,但最终两个体系的状况是相同的。
业界有一些为“终究一致性”而生的音讯行列,如Notify(阿里)、QMQ(去哪儿)等,其规划初衷,就是为了交易体系中的高牢靠告诉。
以一个银行的转账过程来了解终究一致性,转账的需求很简单,假如A体系扣钱成功,则B体系加钱必定成功。反之则一起回滚,像什么都没发生相同。
但是,这个过程中存在许多或许的意外:
- A扣钱成功,调用B加钱接口失利。
- A扣钱成功,调用B加钱接口虽然成功,但获取终究成果时网络反常引起超时。
- A扣钱成功,B加钱失利,A想回滚扣的钱,但A机器down机。
可见,想把这件看似简单的事真实做成,真的不那么简单。一切跨JVM的一致性问题,从技术的角度讲通用的解决方案是:
- 强一致性,分布式业务,但落地太难且成本太高。
- 终究一致性,主要是用“记载”和“补偿”的方法。在做一切的不确定的工作之前,先把工作记载下来,然后去做不确定的工作,成果或许是:成功、失利或是不确定,“不确定”(例如超时等)可以等价为失利。成功就可以把记载的东西清理掉了,关于失利和不确定,可以依托守时使命等方法把一切失利的工作从头搞一遍,直到成功停止。
回到刚才的比如,体系在A扣钱成功的情况下,把要给B“告诉”这件事记载在库里(为了确保最高的牢靠性可以把告诉B体系加钱和扣钱成功这两件事维护在一个本地业务里),告诉成功则删除这条记载,告诉失利或不确定则依托守时使命补偿性地告诉咱们,直到咱们把状况更新成正确的停止。
音讯或许重复,注意音讯的重复和幂等。
(3)广播
假如没有音讯行列,每当一个新的业务接入时,咱们都需要衔接一个新接口;有了音讯行列,咱们只需要关系音讯是否送到到音讯行列,新接入的接口订阅相关的音讯,自己去做处理就行了。
(4)错峰与流控
使用音讯行列,转储两个体系的通讯内容,并在下流体系有才能处理这些音讯的时分再处理这些音讯。试想上下流关于工作的处理才能是不同的。比如,Web前端每秒接受上千万的恳求,并不是什么神奇的工作,只需要加多一点机器,再建立一些LVS负载均衡设备和Nginx等即可。但数据库的处理才能却非常有限,即便运用SSD加分库分表,单机的处理才能仍然在万级。因为成本的考虑,咱们不能苛求数据库的机器数量追上前端。
这种问题同样存在于体系和体系之间,如短信体系或许因为短板效应,速度卡在网关上(每秒几百次恳求),跟前端的并发量不是一个数量级。但用户晚上个半分钟左右收到短信,一般是不会有太大问题的。假如没有音讯行列,两个体系之间经过洽谈、滑动窗口等杂乱的方案也不是说不能实现。但体系杂乱性指数级增加,势必在上游或许下流做存储,并且要处理守时、拥塞等一系列问题。而且每当有处理才能有距离的时分,都需要单独开发一套逻辑来维护这套逻辑。所以,使用中间体系转储两个体系的通讯内容,并在下流体系有才能处理这些音讯的时分,再处理这些音讯,是一套相对较通用的方法。
总结
总而言之,音讯行列不是万能的。关于需要强业务确保而且推迟灵敏的,RPC是优于音讯行列的。
关于一些无关痛痒,或许关于别人非常重要可是关于自己不是那么关怀的工作,可以使用音讯行列去做。
支撑终究一致性的音讯行列,可以用来处理推迟不那么灵敏的“分布式业务”场景,而且相关于粗笨的分布式业务,或许是更优的处理方法。
当上下流体系处理才能存在距离的时分,使用音讯行列做一个通用的“漏斗”。在下流有才能处理的时分,再进行分发。
假如下流有许多体系关怀你的体系发出的告诉的时分,决断地运用音讯行列吧。
写在最终
假如觉得文章对你有点协助,请微信查找并关注「 冰河技术 」微信大众号,跟冰河学习高并发编程技术。
最终,附上并发编程需要掌握的中心技术知识图,祝我们在学习并发编程时,少走弯路。
我有话说: