当前位置: 首页 > 科技观察

消息队列的解耦是骗孩子的

时间:2023-03-18 11:58:09 科技观察

有一点被说得很烂了:使用MQ可以帮助业务系统解耦。这个想法很简单。如果业务状态发生变化时没有MQ,那么其他系统想知道状态发生了变化,所以需要核心流程系统主动通知。例如,在电子商务系统中,订单的状态从创建中切换到正在处理中。客服系统需要知道,风控系统需要知道,用户系统也需要知道。这里通过RPC通知一个典型的依赖。下游系统需要的数据可以在这个RPC中携带,也可以下游系统在请求的时候自行校验。当下游系统数量增多时,核心业务的代码也需要修改。比如新建了一个积分系统,现在订单状态流转积分系统也想知道。当下游增加新的系统时,核心系统需要不断增加调用关系以满足下游新增业务方的需求。这些角点的计算逻辑与订单系统本身无关,但是因为下游需要获取这些数据,所以我们需要使用RPC来调用下游接口。这实在是不合理。当下游系统发生事故时,很容易让核心系统一起躺下:下游炸了,上游肯定也炸了。在这种情况下,核心系统对下游系统的依赖主要是因为核心系统提到了下游系统,而单体系统内部的耦合是一样的。解决这种耦合最简单的方法是在单个模块的情况下使用依赖倒置。在分布式场景下,就是引入消息队列:使用消息队列来解除上游对下游的依赖。修改后,每个订单流只需要将领域事件发送到消息队列即可。如果下游系统有计算需求,自己订阅相关主题即可。当有消息队列的时候,下游增加一个新的系统就到此为止了,那就是天方夜谭了。在最开始的图中,我们的依赖是双向的:双向依赖核心系统因为调用关系依赖下游系统,下游系统依赖核心系统因为下游系统需要使用数据的核心系统。我们使用MQ单向解开依赖,核心系统不调用下游系统。这样,当下游系统崩溃时,就不太可能影响到核心系统的稳定性。隐式依赖导致事故,但无法解决下游系统对核心系统的数据依赖。如果核心系统修改了产生领域事件的代码,仍然会导致下游系统出现故障。在许多情况下,失败是致命的:较大的互联网公司经常重构其核心服务,而下游服务遭到破坏。数据依赖不是对核心系统的显式可见依赖,所以它是核心系统对我的隐式外部依赖。无形的依赖是可怕的,每个人都会慢慢地、逐渐地忽略它,直到出事的那一天。核心系统重新建立对下游系统的依赖。梦想虽然很美好,但是核心系统在为用户服务的过程中,往往会返回一些实时计算出来的数据给用户。这部分数据从何而来?其中许多来自下游计算。对于系统来说,比如我的订单流转系统现在需要在用户的积分达到一定条件的时候做一些特殊的逻辑。随着业务的发展,我们最初去掉的依赖又重新建立起来。循环依赖又回来了!现在两个系统可能会变成你挂我挂的情况。兜兜转转,我们又回到了起点。