一、缘起

一切脱离业务的架构设计与新技术引入都是耍流氓。

引入一个技术之前,首先应该解答的问题是,这个技术解决什么问题。

就像微服务分层架构之前,应该首先回答,为什么要引入微服务,微服务究竟解决什么问题(详见《互联网架构为什么要做微服务?》)。

最近分享了几篇MQ相关的文章:

《MQ如何实现延时消息》

《MQ如何实现消息必达》

《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的方案,新增任何对微信支付的调用,都不需要修改代码啦。

【典型场景4:数据同步】

跨机房数据同步

【典型场景5:削峰消顶】

【典型场景6:处理分布式事务】

五、总结

MQ是一个互联网架构中常见的解耦利器。

到底什么时候该使用MQ?的更多相关文章

  1. 架构-到底什么时候该使用MQ【转】

    点击:<查看原文> 一.缘起 一切脱离业务的架构设计与新技术引入都是耍流氓. 引入一个技术之前,首先应该解答的问题是,这个技术解决什么问题. 就像微服务分层架构之前,应该首先回答,为什么要 ...

  2. 【转】到底什么时候应该用MQ

    原文地址:http://zhuanlan.51cto.com/art/201704/536407.htm 一.缘起 一切脱离业务的架构设计与新技术引入都是耍流氓. 引入一个技术之前,首先应该解答的问题 ...

  3. 170317、到底什么时候该使用MQ?

    一.缘起 一切脱离业务的架构设计与新技术引入都是耍流氓. 引入一个技术之前,首先应该解答的问题是,这个技术解决什么问题. 就像微服务分层架构之前,应该首先回答,为什么要引入微服务,微服务究竟解决什么问 ...

  4. 为什么要使用MQ和到底什么时候要使用MQ

      一.缘起 一切脱离业务的架构设计与新技术引入都是耍流氓. 引入一个技术之前,首先应该解答的问题是,这个技术解决什么问题. 就像微服务分层架构之前,应该首先回答,为什么要引入微服务,微服务究竟解决什 ...

  5. MQ(转)

    1. 到底什么时候该使用MQ? 1). 典型场景一:数据驱动的任务依赖 采用MQ的优点是: a. 不需要预留buffer,上游任务执行完,下游任务总会在第一时间被执行 b. 依赖多个任务,被多个任务依 ...

  6. 初识MQ

    [参考文章]:到底什么时候该使用MQ? 1. 什么是MQ? 消息队列(Message Quene)是一种跨进程的通信机制,用于上下游传递消息. MQ是一种非常常见的上下游“逻辑解耦+物理解耦”的消息通 ...

  7. mq使用场景、不丢不重、时序性

    mq使用场景.不丢不重.时序性.削峰 参考: http://zhuanlan.51cto.com/art/201704/536407.htm http://zhuanlan.51cto.com/art ...

  8. 170331、58到家MQ如何快速实现流量削峰填谷

    问:为什么会有本文? 答:上一篇文章<到底什么时候该使用MQ?>引起了广泛的讨论,有朋友回复说,MQ的还有一个典型应用场景是缓冲流量,削峰填谷,本文将简单介绍下,MQ要实现什么细节,才能缓 ...

  9. 多维度对比5款主流分布式MQ消息队列,妈妈再也不担心我的技术选型了

    1.引言 对于即时通讯网来说,所有的技术文章和资料都在围绕即时通讯这个技术方向进行整理和分享,这一次也不例外.对于即时通讯系统(包括IM.消息推送系统等)来说,MQ消息中件间是非常常见的基础软件,但市 ...

随机推荐

  1. js 实现数据结构 -- 队列

    原文: 在 Javascript 中学习数据结构与算法. 概念: 与栈相反,队列是一种遵循先进先出 (FIFO / First In First Out) 原则的一组有序的项:队列在尾部添加新元素,并 ...

  2. CSS3文字、背景与列表

    一.文本相关属性 1.字体 (1)字体设置 在HTML中,字体通过<font face="字体名称">来设置.在CSS中字体通过font-family属性来控制,里面可 ...

  3. 清北学堂part1

    睡眠质量相当高的一天(滑稽) 整一整都学了啥 1:高精度(相当水,毕竟学过) 2:模运算(?! 这还要讲?) 3:快速幂(还要谢一位学习高数时间为我们讲解的同学...不得不说真的有效,快速幂已经是随手 ...

  4. Luogu5289 十二省联考2019皮配(动态规划)

    将选择导师看成先选阵营再选派系,这样有显然的O(nm2)暴力,即按城市排序后,设f[i][j][k]为前i个学校中第一个阵营有j人第一个派系有k人的方案数,暴力背包. 对于k=0,可以发现选阵营和选派 ...

  5. Luogu5283 十二省联考2019异或粽子(trie/可持久化trie+堆)

    做前缀异或和,用堆维护一个五元组(x,l,r,p,v),x为区间右端点的值,l~r为区间左端点的范围,p为x在l~r中最大异或和的位置,v为该最大异或和,每次从堆中取出v最大的元素,以p为界将其切成两 ...

  6. python学习日记(内置函数补充)

    剩余匿名函数 序列 序列——列表和元组相关的:list和tuple 序列——字符串相关的:str,format,bytes,bytearry,memoryview,ord,chr,ascii,repr ...

  7. echarts 修改y轴name的样式

    option = {    xAxis: {        type: 'category',        data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sa ...

  8. Linux下安装部署Samba共享盘的操作手册

    简述 Samba是在Linux和UNIX系统上实现SMB协议的一个免费软件,由服务器及客户端程序构成.SMB(Server Messages Block,信息服务块)是一种在局域网上共享文件和打印机的 ...

  9. CAS server打包小白教程

    如题,cas是耶鲁大学的一个开源的登录系统,功能齐全,受到很多企业的青睐. 耶鲁大学都不知道那你太out了,我告诉你吧!耶鲁大学就是山东一个椰子树长的很多的地方的大学,很牛逼. 很多新手程序员简历都喜 ...

  10. 迭代器模式-Iterator(Java实现)

    迭代器模式-Iterator 用于访问一个集合中的各个元素, 而又不会暴露集合的内部的细节. 本文展示的例子就是, 在猫群组里, 用迭代器遍历每一只猫. 本文章的例子的继承关系图如下: 其中: Cat ...