十分钟搞懂系列
序号 | 标题 | 链接 |
---|---|---|
1 | 10分钟带你彻底搞懂企业服务总线 | https://blog.csdn.net/belongtocode/article/details/119487731 |
2 | 10分钟带你彻底搞懂微内核架构 | https://blog.csdn.net/belongtocode/article/details/119107837 |
3 | 10分钟带你彻底搞懂服务限流和服务降级 | https://blog.csdn.net/belongtocode/article/details/119107785 |
4 | 10分钟带你彻底搞懂负载均衡 | https://blog.csdn.net/belongtocode/article/details/118977839 |
5 | 10分钟带你彻底搞懂集群容错和服务隔离 | https://blog.csdn.net/belongtocode/article/details/118968771 |
6 | 10分钟带你彻底搞懂注册中心 | https://blog.csdn.net/belongtocode/article/details/118639474 |
7 | 10分钟带你彻底搞懂RPC架构 | https://blog.csdn.net/belongtocode/article/details/118639448 |
我相信你一定有生病去医院的经历,你一般通过什么渠道挂号呢?我们很多人会借助在线挂号 App 或小程序来预约挂号,但你有没有想过,全国有这么多家医院,每个医院内部都可能有自己的信息化系统,在线挂号 App 是怎么帮你准确而高效地找到目标医院和医生的呢?
我们看一下挂号预约的整个业务流程,你就明白了。这里的移动医疗系统就是 App 供应商所开发的系统,而医院信息系统则位于各个医院的内部。
那么,怎么实现这个场景呢?这里的核心需求在于,使用合适的系统集成机制来整合我们自己的移动医疗系统与医院信息系统。而这个整合过程一定具备高扩展性和灵活性,因为医院系统的差异化对系统集成的影响非常大。
你可能会关心,这个过程会涉及到哪些技术难点?包含这么 4 点:
- 怎么对数据进行有效的路由?因为用户要挂某个医生的号,而这个医生任职于某个医院,这就要求把用户请求正确的路由到这家医院的系统中;
- 怎么完成异构系统之间的适配?因为每个医院系统的技术体系可能都有区别,所以需要处理异构系统的数据交互问题;
- 怎么根据特定医院做定制化扩展和过滤?因为不同的医院对问诊排班流程,可能有不同的处理方式,针对特定医院的特定需求,就需要实现对数据的扩展和过滤;
- 怎么实现系统集成组件与平台系统之间的解耦?从架构上讲,平台系统应该专注于处理平台级的业务流程,而系统集成组件只需要处理与医院系统对接方面的逻辑,两者应该各司其职,独立发展。
基于这 4 个难点,显然,通过硬编码的方式实现与外部多个医院系统之间的信息传递和交互就不合适了,需要引入更为合适的技术体系来对整个流程进行建模并实现。
企业服务总线就是用来处理这类场景的最佳技术方案。
什么是企业服务总线?
什么是企业服务总线?就是我们常说的 ESB(Enterprise Service Bus)。我们可以把服务总线当成用来连接分布式异构后端和前端系统的一种中间层软件服务,能够隐藏复杂性,简化数据处理过程。这种中间层软件服务通常被认为是一种系统集成组件,而对系统集成需求的剖析引出了服务总线的整体解决方案。
从这张服务总线解决方案图来看,我们可以知道,所有的数据都被抽象成了一种消息。而消息则在路由器、转换器和端点之间进行流转,这三者也构成了企业服务总线的三大核心组件。我们可以把这三个组件的功能和案例中的需求对应起来,就能清晰的看到每个组件能够解决什么需求:
路由器
我们先来看路由器,路由器需要考虑的核心问题有三个,即:
- 一次路由单条 / 多条数据?
- 路由结果面向一个 / 多个目标?
- 路由是否有状态?
我们对以上三个问题进行抽象,梳理出三个维度,即输入数据数、输出数据数以及有无状态。然后结合这三个维度的不同取值就能获取多种常见的路由器。
我们来看看表中这些路由器各自的特点。
第一个要介绍的路由器是内容路由器(Content-based Router),它的路由效果就是输入一个消息就会路由出一个消息。在这种路由器中,决定路由结果的依据是消息的内容,这里消息内容的概念可以很广,可以是位于消息头中的属性、消息体自身的类型信息,也可以是各种根据业务需要在消息体中进行传输的数据结构。
第二个要介绍的路由器是接收表(Recipient List Router),它的路由效果是输入一个消息则可能输出 0 个或多个消息。我们可以通过设置一定的路由规则,确保消息能够路由到不同的目标对象中。显然,结合前面的案例以及系统扩展性需求,接收表可以满足我们路由到不同医院的需求。
内容路由器和接收表都是属于无状态的路由器,相对比较简单。接下来,我们来看看那些有状态的路由器。有状态是什么意思?就是路由效果依赖于与当前消息相关的多个消息,所以需要对历史消息的处理状态进行维护和管理。分解器(Splitter)和聚合器(Aggregator)就是一对常见的有状态的路由器。如果一个业务场景需要包含对多个消息进行分别处理的需求,就可以使用分解器把原始消息拆分成多个独立的消息进行发送,然后通过聚合器的特定聚合策略实现分解后消息的关联。
这张图就是常见的一种聚合策略,也就是说根据消息头中所包含的“Task001”这个消息编号实现聚合。
转换器
讲完路由器,我们再来看转换器(Transformer)。转换器的应用场景非常明确,就是用来完成异构系统之间数据结构之间的映射。例如在案例中,我们知道各个医院系统采用的可能是完全不同的技术实现体系,对外暴露的也是五花八门的接口定义,这时候就可以使用转换器来消除这些医院系统在数据格式上的差异性。
和路由器一样,转换器在实现上也有多种表现形式。其中,内容扩充器(Enricher)用来完成对消息内容的扩充,也就是为它的消息头或者消息体添加新的数据内容。与内容扩充器相对应的就是内容过滤器(Filter),它用来去掉消息头或消息体中我们所不需要的部分内容。
对应到挂号这个案例中,使用内容过滤器就可以根据用户挂号请求的目标医院信息来过滤那些不需要访问的医院系统,这是一种应用方式。再比如说,如果某家医院需要传入特定的安全标识符才能访问院内系统,那么通过扩充器也很容易在消息头中填充这种安全标识符,而不需要修改消息体本身,效果如下所示:
端点
关于企业服务总线的第三个核心组件是端点(Endpoint),最常用的端点技术就是网关(Gateway)。当应用程序与系统集成组件进行交互时,从系统设计的角度讲我们希望应用程序中的业务代码和用于系统集成的非业务代码耦合度尽量低,也就是说应用程序应该封装对系统集成组件的访问接口,网关就是用来实现这方面需求的。
需要注意的是,网关中应该只包含业务领域层面的接口定义,不应该出现任何与系统集成技术相关的内容,如下图所示。
企业服务总线解决方案
现在你了解了企业服务总线的三个核心组件的作用,让我们对应到挂号案例,梳理一下移动医疗系统的实现效果图:
可以看到,我们综合应用了服务总线中的多个核心组件完成了对整个系统集成方案,包括:
- 网关:用于降低系统实现系统集成组件与业务代码上的耦合度
- 内容扩充器:用于完成安全认证等特定医院所需的定制化需求
- 数据结构转换器:用于完成针对医院异构系统的数据转换
- 接收表:用于根据消息头中携带的目标医院信息自动路由到对应的医院信息系统
总的来说,服务总线本质上是一种架构设计方案,想要实现这一方案,我们可以借助于 Mule ESB、Apache Camel 和 Spring Integration 等主流的系统集成开发框架。
参考文章:
整理于极客时间每日一课对应文章