细数软件架构中的解耦( 三 )


事件流订阅事件流订阅的设计理念是将瞬间的过程化调用转变成可回放的指令,对指令的响应可以不用再预定义 。事件流订阅,在应用层表现为 Mediator 中介模式,在架构层表现为 Broker 消息模式 。
应用层 -Mediator 中介模式
A 直接调用 B,意味着 A 对 B 产生了强依赖 。当然我们可以通过面向接口编程,把这个依赖降低,降低到只依赖接口,不依赖实现 。简单说,我们只依赖对事情的处理结果,不依赖于如何实现这个处理结果 。
但是这还不够,因为我们还依赖了接口,接口意味着对处理语义的刻画 。现实中有些情况,连语义的描述都要发生变化,也就是接口都要发生变化,如何进一步解耦呢?如下图:

细数软件架构中的解耦

文章插图
 
A 不直接调用 B,而通过中介 Mediator,解耦两步:
  • 先由 A 调用 Mediator: A 持有 Mediator 的引用,执行 Mediator 的方法,即 mediator.publish(e) 。
  • 再由 Mediator 调用 B: 为了解耦 Mediator 对外界的依赖,我们用面向接口 EventHandler 来实现依赖反转 。让 B 来实现 EventHandler,当然如果 B 已经存在,或更有话语权,依然应该遵循依赖反转的原则,只不过 Mediator 模式的推进方可以再实现一个 Adaptor,来帮助既有的 B 适配到 EventHandler 。
有了上述的设计模式后,具体的执行分三步:
  • 订阅:通过 mediator.subscribe(b) 把未来的事件处理提前注册到 Mediator 。
  • 发布:A 向 Mediator 发布自己的事件 。注意这个理念特别重要,A 仅仅发布发生了什么事情,A 并没有直接调用 B 声明对事情的处理 。也就是 A 连对 B 的接口都不再依赖了!举个例子,比如新员工入职,刚开始要为员工办理磁条卡,只是办理磁条卡的供应商可能是甲,也可能是乙 。这叫面向接口编程,但这还不够,因为随着公司的发展,现在新员工入职,有人脸识别了,不用再办磁条卡了,而是要登记人脸识别,另外员工福利更好了,对异地公干的新员工入职还会发放一笔安家费,这些都是之前的“接口”没有描述的 。
  • 执行:当 mediator 收到 A 的事件后(A 调用了 mediator.publish(e)),mediator 会通过 EventHandler 来回调预先通过 mediator.subscribe(b) 注册的处理类 。
上述 Mediator,有些局限性,对所有的 Event,只能有一种 EventHandler 。如果我们把 Mediator 升级为一种通用的处理机制,一种平台,自然会有各种各样的 Event,自然会我们会对 Event 做个分类或分组 。我们把 Event 的分类或分组,叫做 Topic;而把 Event 理解为 Topic 这个类里面的具体实例 。并在 Mediator 里面维护,从 Topic 到 EventHandler 的一组处理器 。如下图所示:
细数软件架构中的解耦

文章插图
 
可以看到上述架构通过 Map<Topic, List> resolver 来维护从 Topic 到 EventHandler 的一组处理 。为什么是 List,而不是 EventHandler 呢?为了更加灵活,比如上文提到的「现在新员工入职,有人脸识别了,不用再办磁条卡了,而是要登记人脸识别,另外员工福利更好了,对异地公干的新员工入职还会发放一笔安家费」 。
架构层 -Broker 消息模式
细数软件架构中的解耦

文章插图
 
上图的 Broker 模式,跟 Mediator 模式其实没有本质的不同,只不过 Broker 更加突出了借助消息中间件 MQ 实现异步 。客户端提交一个委托,Broker 持久化完成,并回复 ACK,表示委托已收到 。接着委托的消费处理,可以是离线的 。通常需要支持 Group 机制:Group 内部多个 Instance 是负载均衡的,它们共同瓜分委托消息的处理;而 Group 间是冗余复制的,它们各自消费各自的,相互之间隔离,有助于实现业务可拓展性 。
比如一个新员工入职,它产生一个“新人入职”事件,然后行政部门会为其准备工卡、财务部门会为其准备工资卡、HR 部门会为其缴纳社保 。当然,随着公司业务发展,可能还会增加,比如业务部门的业务培训,风控部门的合规性培训等 。
跟前面说的 Proxy 模式,相同点在于它们都是在架构层面实现可拓展性 。不同点是,Proxy 模式支持的是 PreHandler 和 PostHandler;而 Broker 模式支持的是 MidHandler 。
关于作者
作者李伟,研究微服务与大数据方向,擅长中台架构敏捷性课题 。就职于京东零售,担任资深架构师,加入京东前曾就职于搜狐和百度 。

【细数软件架构中的解耦】


推荐阅读