关键词:
原文地址:http://mp.weixin.qq.com/s/Brd-j3IcljcY7BV01r712Q
转自:https://blog.csdn.net/xybelieve1990/article/details/70313216/
一、缘起
一切脱离业务的架构设计与新技术引入都是耍流氓。
引入一个技术之前,首先应该解答的问题是,这个技术解决什么问题。
就像微服务分层架构之前,应该首先回答,为什么要引入微服务,微服务究竟解决什么问题(详见《互联网架构为什么要做微服务?》)。
最近分享了几篇MQ相关的文章:
不少网友询问,究竟什么时候使用MQ,MQ究竟适合什么场景,故有了此文。
二、MQ是干嘛的
消息总线(Message Queue),后文称MQ,是一种跨进程的通信机制,用于上下游传递消息。
在互联网架构中,MQ是一种非常常见的上下游“逻辑解耦+物理解耦”的消息通信服务。
使用了MQ之后,消息发送上游只需要依赖MQ,逻辑上和物理上都不用依赖其他服务。
三、什么时候不使用消息总线
既然MQ是互联网分层架构中的解耦利器,那所有通讯都使用MQ岂不是很好?这是一个严重的误区,调用与被调用的关系,是无法被MQ取代的。
MQ的不足是:
1)系统更复杂,多了一个MQ组件
2)消息传递路径更长,延时会增加
3)消息可靠性和重复性互为矛盾,消息不丢不重难以同时保证
4)上游无法知道下游的执行结果,这一点是很致命的
举个栗子:用户登录场景,登录页面调用passport服务,passport服务的执行结果直接影响登录结果,此处的“登录页面”与“passport服务”就必须使用调用关系,而不能使用MQ通信。
无论如何,记住这个结论:调用方实时依赖执行结果的业务场景,请使用调用,而不是MQ。
四、什么时候使用MQ
【典型场景一:数据驱动的任务依赖】
什么是任务依赖,举个栗子,互联网公司经常在凌晨进行一些数据统计任务,这些任务之间有一定的依赖关系,比如:
1)task3需要使用task2的输出作为输入
2)task2需要使用task1的输出作为输入
这样的话,tast1, task2, task3之间就有任务依赖关系,必须task1先执行,再task2执行,载task3执行。
对于这类需求,常见的实现方式是,使用cron人工排执行时间表:
1)task1,0:00执行,经验执行时间为50分钟
2)task2,1:00执行(为task1预留10分钟buffer),经验执行时间也是50分钟
3)task3,2:00执行(为task2预留10分钟buffer)
这种方法的坏处是:
1)如果有一个任务执行时间超过了预留buffer的时间,将会得到错误的结果,因为后置任务不清楚前置任务是否执行成功,此时要手动重跑任务,还有可能要调整排班表
2)总任务的执行时间很长,总是要预留很多buffer,如果前置任务提前完成,后置任务不会提前开始
3)如果一个任务被多个任务依赖,这个任务将会称为关键路径,排班表很难体现依赖关系,容易出错
4)如果有一个任务的执行时间要调整,将会有多个任务的执行时间要调整
无论如何,采用“cron排班表”的方法,各任务耦合,谁用过谁痛谁知道(采用此法的请评论留言)
优化方案是,采用MQ解耦:
1)task1准时开始,结束后发一个“task1 done”的消息
2)task2订阅“task1 done”的消息,收到消息后第一时间启动执行,结束后发一个“task2 done”的消息
3)task3同理
采用MQ的优点是:
1)不需要预留buffer,上游任务执行完,下游任务总会在第一时间被执行
2)依赖多个任务,被多个任务依赖都很好处理,只需要订阅相关消息即可
3)有任务执行时间变化,下游任务都不需要调整执行时间
需要特别说明的是,MQ只用来传递上游任务执行完成的消息,并不用于传递真正的输入输出数据。
【典型场景二:上游不关心执行结果】
上游需要关注执行结果时要用“调用”,上游不关注执行结果时,就可以使用MQ了。
举个栗子,58同城的很多下游需要关注“用户发布帖子”这个事件,比如招聘用户发布帖子后,招聘业务要奖励58豆,房产用户发布帖子后,房产业务要送2个置顶,二手用户发布帖子后,二手业务要修改用户统计数据。
对于这类需求,常见的实现方式是,使用调用关系:
帖子发布服务执行完成之后,调用下游招聘业务、房产业务、二手业务,来完成消息的通知,但事实上,这个通知是否正常正确的执行,帖子发布服务根本不关注。
这种方法的坏处是:
1)帖子发布流程的执行时间增加了
2)下游服务当机,可能导致帖子发布服务受影响,上下游逻辑+物理依赖严重
3)每当增加一个需要知道“帖子发布成功”信息的下游,修改代码的是帖子发布服务,这一点是最恶心的,属于架构设计中典型的依赖倒转,谁用过谁痛谁知道(采用此法的请评论留言)
优化方案是,采用MQ解耦:
1)帖子发布成功后,向MQ发一个消息
2)哪个下游关注“帖子发布成功”的消息,主动去MQ订阅
采用MQ的优点是:
1)上游执行时间短
2)上下游逻辑+物理解耦,除了与MQ有物理连接,模块之间都不相互依赖
3)新增一个下游消息关注方,上游不需要修改任何代码
典型场景三:上游关注执行结果,但执行时间很长
有时候上游需要关注执行结果,但执行结果时间很长(典型的是调用离线处理,或者跨公网调用),也经常使用回调网关+MQ来解耦。
举个栗子,微信支付,跨公网调用微信的接口,执行时间会比较长,但调用方又非常关注执行结果,此时一般怎么玩呢?
一般采用“回调网关+MQ”方案来解耦:
1)调用方直接跨公网调用微信接口
2)微信返回调用成功,此时并不代表返回成功
3)微信执行完成后,回调统一网关
4)网关将返回结果通知MQ
5)请求方收到结果通知
这里需要注意的是,不应该由回调网关来调用上游来通知结果,如果是这样的话,每次新增调用方,回调网关都需要修改代码,仍然会反向依赖,使用回调网关+MQ的方案,新增任何对微信支付的调用,都不需要修改代码啦。
五、总结
MQ是一个互联网架构中常见的解耦利器。
什么时候不使用MQ?
上游实时关注执行结果
什么时候使用MQ?
1)数据驱动的任务依赖
2)上游不关心多下游执行结果
3)异步返回执行时间长
究竟什么时候该使用mq?(代码片段)
...流氓。引入一个组件,最先该解答的问题是,此组件解决什么问题。MQ,互联网技术体系中一个常见组件,究竟什么时候不使用MQ,究竟什么时候使用MQ,MQ究竟适合什么场景,是今天要分享的内容。MQ是什么?消息总线(MessageQueu... 查看详情
到底什么时候该用多线程
...相关的线程类库或API改善程序,并使其正常运行;但是,到底存不存在一种判断依据,能够明确的指导我们正确地使用多线程机制来解决问题呢?笔者对此进行了一番思考,在此说说我的想法以供参考。 查看详情
牛逼哄哄的mq到底有啥用?(代码片段)
作者:卓庆森http://www.cnblogs.com/zhuoqingsen/p/MQ.html我走过最长的路是你的套路女:二号男嘉宾,假如我们牵手成功后,你会买名牌包包给我吗?男:那你会听话吗?女:会听话。男:听话咱不买!OK那么消息队列MQ有什么套路呢?(... 查看详情
什么时候用mq
...外音:发送方与消费方,逻辑上和物理上都不依赖彼此。什么时候不使用MQ?当调用方需要关心消息执行结果时,通常不使 查看详情
初识mq
1.什么是MQ? 消息队列(MessageQuene)是一种跨进程的通信机制,用于上下游传递消息。 MQ是一种非常常见的上下游“逻辑解耦+物理解耦”的消息通信服务。 使用了MQ之后,消息发送上游只需要依赖MQ,逻辑上和... 查看详情
rabbitmq--面试官问为什么要使用mq,应该怎么回答
...他的消息中间件,可能在MQ方面的第一个问题就是问:为什么要使用MQ面试官期望的回答 1、项目中有什么业务场景需要用到MQ 2、但是用了MQ,会带来很多问题,有什么缺点所以,我们首先要回答的就是MQ的使用场景,在第... 查看详情
bi驾驶舱到底是什么,该如何正确使用
...,可是在这种过程中,很多人都不是特别的了解bi驾驶舱到底是什么,又是如何来进行正确使用的呢? 免费试用FineBIBi驾驶舱到底是什么其实这就相当于是商务智能的一种软件,是专门为了企业管理而设计的,能够有效的创... 查看详情
互联网面试必杀:如何保证消息中间件全链路数据100%不丢失(代码片段)
...生产环境使用消息中间件技术的时候,从前到后的全链路到底如何保证数据不能丢失。这个问题,在互联网公司面试的时候高频出现,而且也是非常现实的生产环境问题。如果你的简历中写了自己熟悉MQ技术(RabbitMQ、RocketMQ、Kaf... 查看详情
java的输入与输出流当中,什么时候该使用字符流?什么时候该使用字节流?
1.InputStream和OutputStream,两个是为字节流设计的,主要用来处理字节或二进制对象,2.Reader和Writer.两个是为字符流(一个字符占两个字节)设计的,主要用来处理字符或字符串.字符流处理的单元为2个字节的Unicode字符,分别操作字符、... 查看详情
yum到底是干什么的?
...用yum的时候同样是这样,但是yum究竟是什么?他到底起到了什么样的作用? 接下来跟随小编的步伐,我们一起来探索。1、开胃篇 在本节中,小编会给大家 查看详情
mq消息队列及常见mq比较
一、什么是消息队列 我们可以把消息队列比作是一个存放消息的容器,当我们需要使用消息的时候可以取出消息供自己使用。消息队列是分布式系统中重要的组件,使用消息队列主要是为了通过异步处理提高系统性能和削峰... 查看详情
工程实践:到底要不要使用智能指针(代码片段)
工程实践:到底要不要使用智能指针前言从需求开始探讨问题智能指针现状unique_ptr示例shard_ptr接口该不该使用智能指针智能指针作为函数参数智能指针作为函数返回值如何选择智能指针注意不要踩的“坑”总结参考资料前言... 查看详情
rabbitmq原理与相关操作(代码片段)
...补齐。引入MQ话题什么时候会用到MQ可能很多人有疑惑:MQ到底是什么?哪些场景下要使用MQ?前段时间安装了RabbitMQ,现在就记录下自己的学习心得吧。首先看段程序:classProgramstaticvoidMain(string[]args)newThread(Write).Start();newThread(Write... 查看详情
Heroku到底是啥?
】Heroku到底是啥?【英文标题】:WhatexactlyisHeroku?Heroku到底是什么?【发布时间】:2012-06-1601:13:42【问题描述】:我刚开始在Rails上学习Ruby,我想知道Heroku到底是什么?我知道它的云可以帮助我们避免使用服务器?我们什么时候... 查看详情
到底什么是es索引?
你会发现,其实在ES里面,索引扮演的角色其实并不是存储,而是“索引”,看起来有点傻,但是其实我之前一直理解索引是存储,其实从命名上可以看出来,索引其实是分片的索引,分片的字典,记录了每个分片的位置,索引... 查看详情
activemq初步学习
今天开始学习activeMq。什么是MQ,MQ是消息中间件。消息模型:点对点模型和发布订阅模型。点对点模型:生产者生产消息,放到MQ中,消费者消费消息。每个消息如果不过期,则会被一个消费者消费。消费者接收到消息会返回成... 查看详情
二值信号量和互斥锁到底有什么区别?
在说明之前我先抛出结论:互斥锁和二值信号量在使用上非常相似,但是互斥锁解决了优先级翻转的问题假定我们现在有三个任务,task1,task2,task3,任务优先级task1最高,然后依次降低。我们知道在系统调度的时候当两个任务... 查看详情
什么时候适合使用 KnownType 属性?
】什么时候适合使用KnownType属性?【英文标题】:WhenisitappropriatetousetheKnownTypeattribute?【发布时间】:2011-03-1105:21:01【问题描述】:阅读MSDN参考后,我仍然对何时使用KnownType属性有疑问。我知道该属性将类型信息传达给序列化程... 查看详情