做网站的公司有哪些岗位,html5门户网站模版,wordpress配置文件修改,南昌建设企业网站公司一、缘起
一切脱离业务的架构设计与新技术引入都是耍流氓。
引入一个技术之前#xff0c;首先应该解答的问题是#xff0c;这个技术解决什么问题。
就像微服务分层架构之前#xff0c;应该首先回答#xff0c;为什么要引入微服务#xff0c;微服务究竟解决什么问题首先应该解答的问题是这个技术解决什么问题。
就像微服务分层架构之前应该首先回答为什么要引入微服务微服务究竟解决什么问题详见《互联网架构为什么要做微服务》。
最近分享了几篇MQ相关的文章
《MQ如何实现延时消息》
《MQ如何实现消息必达》
《MQ如何实现幂等性》
不少网友询问究竟什么时候使用MQMQ究竟适合什么场景故有了此文。
二、MQ是干嘛的
消息总线Message Queue后文称MQ是一种跨进程的通信机制用于上下游传递消息。 在互联网架构中MQ是一种非常常见的上下游“逻辑解耦物理解耦”的消息通信服务。
使用了MQ之后消息发送上游只需要依赖MQ逻辑上和物理上都不用依赖其他服务。
三、什么时候不使用消息总线 既然MQ是互联网分层架构中的解耦利器那所有通讯都使用MQ岂不是很好这是一个严重的误区调用与被调用的关系是无法被MQ取代的。
MQ的不足是
1系统更复杂多了一个MQ组件
2消息传递路径更长延时会增加
3消息可靠性和重复性互为矛盾消息不丢不重难以同时保证
4上游无法知道下游的执行结果这一点是很致命的
举个栗子用户登录场景登录页面调用passport服务passport服务的执行结果直接影响登录结果此处的“登录页面”与“passport服务”就必须使用调用关系而不能使用MQ通信。
无论如何记住这个结论调用方实时依赖执行结果的业务场景请使用调用而不是MQ。
四、什么时候使用MQ
【典型场景一数据驱动的任务依赖】
什么是任务依赖举个栗子互联网公司经常在凌晨进行一些数据统计任务这些任务之间有一定的依赖关系比如
1task3需要使用task2的输出作为输入
2task2需要使用task1的输出作为输入
这样的话tast1, task2, task3之间就有任务依赖关系必须task1先执行再task2执行载task3执行。 对于这类需求常见的实现方式是使用cron人工排执行时间表
1task10:00执行经验执行时间为50分钟
2task21:00执行为task1预留10分钟buffer经验执行时间也是50分钟
3task32:00执行为task2预留10分钟buffer
这种方法的坏处是
1如果有一个任务执行时间超过了预留buffer的时间将会得到错误的结果因为后置任务不清楚前置任务是否执行成功此时要手动重跑任务还有可能要调整排班表
2总任务的执行时间很长总是要预留很多buffer如果前置任务提前完成后置任务不会提前开始
3如果一个任务被多个任务依赖这个任务将会称为关键路径排班表很难体现依赖关系容易出错
4如果有一个任务的执行时间要调整将会有多个任务的执行时间要调整
无论如何采用“cron排班表”的方法各任务耦合谁用过谁痛谁知道采用此法的请评论留言
优化方案是采用MQ解耦
1task1准时开始结束后发一个“task1 done”的消息
2task2订阅“task1 done”的消息收到消息后第一时间启动执行结束后发一个“task2 done”的消息
3task3同理
采用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异步返回执行时间长