一 前情回顾
上篇文章《哥们, 你们的系统架构中为什么要引入消息中间件呢?》, 给大家讲了讲消息中间件引入系统架构的作用, 主要是解决哪些问题的.
其比较常见的实践场景是:
复杂系统的解耦
复杂链路的异步调用
瞬时高峰的削峰处理
二 正式开始
这篇文章给大家讲讲, 如果你在系统架构里引入了消息中间件之后, 会有哪些缺点?
1. 系统可用性降低
首先是你的系统整体可用性绝对会降低, 给你举个例子, 我们就拿之前的一幅图来说明.
比如说一个核心链路里面, 系统 A -> 系统 B -> 系统 C, 然后系统 C 是通过 MQ 异步调用系统 D 的.
看起来很好, 你用这个 MQ 异步化的手段解决了一个核心链路执行性能过差的问题.
但是你有没有考虑另外一个问题, 就是万一你依赖的那个 MQ 中间件突然挂掉了怎么办? 这个还真的不是异想天开, MQ,Redis,MySQL 这些组件都有可能会挂掉.
一旦你的 MQ 挂了, 就导致你的系统的核心业务流程中断了. 本来你要是不引入 MQ 中间件, 那其实就是一些系统之间的调用, 但是现在你引入了 MQ, 就导致你多了一个依赖. 一旦多了一个依赖, 就会导致你的可用性降低.
因此, 一旦引入了 MQ 中间件, 你就必须去考虑这个 MQ 是如何部署的, 如何保证高可用性.
甚至在复杂的高可用的场景下, 你还要考虑如果 MQ 一旦挂了以后, 你的系统有没有备用兜底的技术方案, 可以保证系统继续运行下去.
2. 系统稳定性降低
还是上面那张图, 大家再来看一下.
不知道大家有没有发现一个问题, 这个链路除了 MQ 中间件挂掉这个可能存在的隐患之外, 可能还有一些其他的技术问题.
比如说, 莫名其妙的, 系统 C 发了一个消息到 MQ, 结果那个消息因为网络故障等问题, 就丢失了. 这就导致系统 D 没有收到那条消息.
这可就惨了, 这样会导致系统 D 没完成自己该做的任务, 此时可能整个系统会出现业务错乱, 数据丢失, 严重的 bug, 用户体验很差等各种问题.
这还只是其中之一, 万一说系统 C 给 MQ 发送消息, 不小心一抽风重复发了一条一模一样的, 导致消息重复了, 这个时候该怎么办?
可能会导致系统 D 一下子把一条数据插入了两次, 导致数据错误, 脏数据的产生, 最后一样会导致各种问题.
或者说如果系统 D 突然宕机了几个小时, 导致无法消费消息, 结果大量的消息在 MQ 中间件里积压了很久, 这个时候怎么办?
即使系统 D 恢复了, 也需要慢慢的消费数据来进行处理.
所以这就是引入 MQ 中间件的第二个大问题, 系统稳定性可能会下降, 故障会增多, 各种各样乱七八糟的问题都可能产生.
而且一旦产生了一个问题, 就会导致系统整体出问题. 就需要为了解决各种 MQ 引发的技术问题, 采取很多的技术方案.
关于这个, 我们后面会用专门的文章聊聊 MQ 中间件的这些问题的解决方案, 包括:
消息高可靠传递 (0 丢失)
消息幂等性传递 (绝对不重复)
百万消息积压的线上故障处理
3. 分布式一致性问题
引入消息中间件, 还有分布式一致性的问题.
举个例子, 比如说系统 C 现在处理自己本地数据库成功了, 然后发送了一个消息给 MQ, 系统 D 也确实是消费到了.
但是结果不幸的是, 系统 D 操作自己本地数据库失败了, 那这个时候咋办?
系统 C 成功了, 系统 D 失败了, 会导致系统整体数据不一致了啊.
所以此时又需要使用可靠消息最终一致性的分布式事务方案来保障.
三 总结
最后, 我们来做一个简单的小结.
在面试中要答好这个问题, 首先一定要熟悉 MQ 这个技术的优缺点. 了解清楚把他引入系统是为了解决哪些问题的, 但是他自身又会带来哪些问题.
此外, 对于引入 MQ 以后, 是否对他自身可能引发的问题有一些方案的设计, 来保证你的系统高可用, 高可靠的运行, 保证数据的一致性. 这个也有做好相应的准备.
我做开发十多年的时间, 如果大家对于学习 java 的学习方法, 学习路线以及你不知道自己应该是自学还是培训的疑问, 都可以随时来问我, 大家可以加我的 java 交流学习 qun:615741636.qun 内有学习教程以及开发工具.
来源: http://www.jianshu.com/p/393149420416