面试官问:为何须要消息队列?使用消息队列有什么好处?

来源:http://t.cn/EogJKg4前端

目录

1、消息队列的特性
2、为何须要消息队列?
3、使用消息队列有什么好处?
4、为何须要分布式?
5、分布式环境下须要解决哪些问题?
6、如何实现?
7、常见消息队列对比和选型mysql

1、消息队列的特性

业务无关,一个具备普适性质的消息队列组件不须要考虑上层的业务模型,只作好消息的分发就能够了,上层业务的不一样模块反而须要依赖消息队列所定义的规范进行通讯。react

FIFO,先投递先到达的保证是一个消息队列和一个buffer的本质区别。sql

容灾,对于普适的消息队列组件来讲,节点的动态增删和消息的持久化,都是支持其容灾能力的重要基本特性。固然,这个特性对于游戏服务器中大部分应用中的消息队列来讲不是必须的,这个也是跟应用情景有关的,不少时候没有这种持久化的需求。数据库

性能,这个没必要多说了,消息队列的吞吐量上去了,整个系统的内部通讯效率也会有提升。后端

2、为何须要消息队列?

当系统中出现“生产“和“消费“的速度或稳定性等因素不一致的时候,就须要消息队列,做为抽象层,弥合双方的差别。“ 消息 ”是在两台计算机间传送的数据单位。消息能够很是简单,例如只包含文本字符串;也能够更复杂,可能包含嵌入对象。消息被发送到队列中,“ 消息队列 ”是在消息的传输过程当中保存消息的容器 。缓存

举几个例子安全

1)业务系统触发短信发送申请,但短信发送模块速度跟不上,须要未来不及处理的消息暂存一下,缓冲压力。就能够把短信发送申请丢到消息队列,直接返回用户成功,短信发送模块再能够慢慢去消息队列中取消息进行处理。服务器

2)调远程系统下订单成本较高,且由于网络等因素,不稳定,攒一批一块儿发送。微信

3)任务处理类的系统,先把用户发起的任务请求接收过来存到消息队列中,而后后端开启多个应用程序从队列中取任务进行处理。

3、使用消息队列有什么好处?

3.一、提升系统响应速度

使用了消息队列,生产者一方,把消息往队列里一扔,就能够立马返回,响应用户了。无需等待处理结果。

处理结果可让用户稍后本身来取,如医院取化验单。也可让生产者订阅(如:留下手机号码或让生产者实现listener接口、加入监听队列),有结果了通知。得到约定将结果放在某处,无需通知。

3.二、提升系统稳定性

考虑电商系统下订单,发送数据给生产系统的状况。电商系统和生产系统之间的网络有可能掉线,生产系统可能会因维护等缘由暂停服务。若是不使用消息队列,电商系统数据发布出去,顾客没法下单,影响业务开展。两个系统间不该该如此紧密耦合。应该经过消息队列解耦。同时让系统更健壮、稳定。

异步化、解耦、消除峰值

以上三点其实能够用一个例子来解释——设想有一款MMO游戏,没有人肉写的缓存层或者ORM,全部逻辑节点都直连MySQL,逻辑节点内除了要关注场景、战斗、交互等复杂逻辑之外,还要有个拼SQL语句的模块,想一想简直是蛋疼。先考虑一下这样设计的弊端所在:

  • 逻辑节点与Db的交互会有大量IO,即便把与Db交互的模块耦合在逻辑节点内,其实现对你来讲是黑盒,若是内部是同步实现的,那就直接卡你游戏主逻辑,就由于一次存盘操做,玩家们都掉线了,服务器也能够关掉了。

  • 那么咱们改进一下,针对1的状况,能够把这个模块作到一个线程里挂在逻辑节点上。这样其实逻辑节点跟这个Db前端模块的交互就会基于一个比较原始的消息队列。可是这样还有一个坏处,那就是这两种任务一种是计算密集的(玩家的逻辑处理)、一种是IO密集的(只负责写入读取MySQL),搞到一个节点中,扩展起来会很是麻烦,并且耦合度过高。好比说如今发现场景放单节点上有瓶颈,要按场景分节点,那么这种挂在上面的数据模块怎么跟其余场景的交互呢?

  • 峰值的问题。在分布式系统中,一次分布式事务关联的是多个节点,其中每个节点出现问题都会成为整个事务处理流程中的瓶颈。若是逻辑节点与数据库之间没有一个起到缓冲做用的节点,那就是每次操做都要访问数据库,对于MMO来讲,一个玩家上线load几百K数据,一个服10万个玩家上线已经足够搞垮一个mysql节点了。若是直接搞垮仍是比较好的结果,至少是前面的玩家确实登陆上去了而且能够正常游戏,后面的玩家登陆不上。可是很惋惜,十年前开始流行的C10K说法就是在讲:并发量上来以后,会形成chain reaction,大量的并发不会直接挂掉你的mysql节点,可是会拖慢速度,下降吞吐量,一个玩家的请求因为处理时间太长,致使玩家放弃重试,可是对于后端来讲,对该玩家以前的处理过程消耗的资源就所有浪费了,陷入恶性循环。

因此,这种情景下,一个介于逻辑节点和db节点之间的缓存节点就是理所固然的事情了。这个缓存节点其实不少时候也能够看做是一个更复杂的消息队列节点。

4、为何须要分布式?

4.一、多系统协做须要分布式

消息队列中的数据须要在多个系统间共享数据才能发挥价值。因此必须提供分布式通讯机制、协同机制。

4.二、单系统内部署环境须要分布式

单系统内部,为了更好的性能、为了不单点故障,多为集群环境。集群环境中,应用运行在多台服务器的多个JVM中;数据也保存在各类类型的数据库或非数据库的多个节点上。为了知足多节点协做须要,须要提供分布式的解决方案。

5、分布式环境下须要解决哪些问题?

5.一、并发问题

需进行良好的并发控制。确保“线程安全“。不要出现一个订单被出货两次。不要出现顾客A下的单,发货发给了顾客B等状况。

5.二、简单的、统一的操做机制

需定义简单的,语义明确的,业务无关的,恰当稳妥的统一的访问方式。

5.三、容错

控制好单点故障,确保数据安全。

5.四、可横向扩展

可便捷扩容。

6、如何实现?

成熟的消息队列中间件产品太多了,族繁不及备载。成熟产品通过验证,接口规范,可扩展性强。

结合事业环境因素、组织过程遗产、实施运维考虑、技术路线考虑、开发人员状况等缘由综合考虑。

7、常见消息队列对比和选型

本文分享自微信公众号 - JAVA高级架构(gaojijiagou)。
若有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一块儿分享。

相关文章
相关标签/搜索