mq 不仅是削峰填谷,也不仅是解耦服务,还有降低代码复杂性、增加稳定性的作用。中间件是一个稳定的、没有逻辑的、仅仅存储数据的。

现象

比如我们代码中安置逻辑里的 resource 的同步。

节点定时上报给 zoneleader,为了避免重复上报,节点自身又缓存了资源信息,每次上报前,先计算当前资源信息,然后和上一次缓存的资源信息对比,如果有差异,再汇报。

zoneleader 还会变。

上面两点,带来的复杂性:

  1. zoneleader 变了之后,节点得知道;
  2. 节点得区分 zoneleader 是否变化了,变了就直接上报资源信息;
  3. 节点不知道 zoneleader 用的资源信息是什么,说不定自己的缓存因为各种原因就不对呢;
  4. 处理异常情况能力弱。比如 zoneleader 因为个别原因更新失败,后续节点因为缓存的原因就不重试了。

这种方式虽然没有中心化的依赖问题,但是每个功能都需要处理上述类似的问题。

这是一种繁琐的、让代码复杂性大幅膨胀的方式,也是一种功能之间重复的、却不能统一处理的多余。

也是客户端和服务端相互紧密耦合的一种方式。

用中间件的方式

如果用中间件的方式:

  • 客户端可以拉下来和当前资源对比;
  • 服务端定期从中间件拉取资源即可;
  • 中间件是一个稳定的、没有逻辑的、仅仅存储数据的。

所以:

  • 客户端的逻辑只需要客户端处理,不变接口就不会影响服务端;
  • 服务端也一样,自己处理逻辑,不用管客户端;
  • 节点也不用关心 zoneleader 是不是变化了,它只想一个固定的中间件地址推送就行了;
  • zoneleader 变化了,也不用想办法通知到其他节点,存储到中间件就行。

好处:

  1. 解耦;
  2. 不会相互影响了;
  3. 节点也知道当前使用的资源信息是什么样的,可以对比。

中间件依赖本身可以通过各种高可用方式保证其可用性,在现在已经不是什么主要矛盾或问题了。

小结

  • mq 不仅是削峰填谷,也不仅是解耦服务;
  • 还有降低代码复杂性、增加稳定性的作用;
  • 中间件是一个稳定的、没有逻辑的、仅仅存储数据的;
  • 客户端和服务端通过中间件解耦,互不影响;
  • 中间件依赖可以通过高可用方式保证可用性,不是主要矛盾。