架构风格之分布式风格

现代软件开发一大现状和问题就是容易形成信息孤岛,即每个业务部门和产品线根据自身的业务需求设计相应的架构体系并进行实现,这些独立的系统保存着业务系统的核心数据并运行于独立的进程环境中。涉及到组织架构、团队文化、技术体系等因素,仅仅通过系统内部重构很大程度上只能缓解而不能消除信息孤岛的产生,这就需要使用某种手段进行业务服务整合,分布式架构风格的目的就在于此。分布式作为一种基础架构风格为不同系统之间的交互提供通信范式,从而有效屏蔽底层平台细节。分布式架构风格有以下三种主要的表现形式:

1. Broker

Broker[9]是非常常见的一种架构风格,分布式系统之间通过远程过程调用(Remote Procedure Call,RPC)进行相互作用。服务端应用组件注册自己到Broker,通过暴露接口的方式允许客户端接入服务。客户端则通过Broker发送请求,Broker转发请求到服务端,调用服务端应用组件并将生成的结果回发给客户端。通过Broker,业务服务之间可以通过发送请求访问远程的服务(见下图)。

Broker中存在几个核心组件:Client,Server,Proxy以及分别面向Client和Server的Broker,其中最重要的Broker可以被看成消息转发器,同时也负责一些控制和管理操作。服务器端Broker需要提供注册服务的接口给Server,而客户端可以通过客户端Broker发现远程服务,客户端Broker保证了通讯的透明性,使Client调用远程服务就像调用本地的服务一样。通过客户端Broker和服务器端Broker之间的数据发送和接收实现分布式环境下的远程通信。

2. 消息传递

消息传递(Messaging)机制能够降低技术、空间和时间耦合。如下图所示,消息传递机制在消息发送方和消息接收方之间添加了存储转发(Store and Forward)功能。存储转发计算机网络领域使用最为广泛的技术之一,基本思想就是将数据先缓存起来,再根据其目的地址将该数据发送出去。显然,有了存储转发机制之后,消息发送方和消息接收方之间并不需要相互认识,也不需要同时在线,更加不需要采用同样的实现技术。紧耦合的单阶段方法调用就转变成松耦合的两阶段过程,技术、空间和时间上的约束通过中间层得到显著缓解,这个中间层就是消息传递系统(Messaging System)。

在消息传递系统中,消息的发送者称为生产者(Producer),负责产生消息,一般由业务系统充当生产者;消息的接收者称为消费者(Consumer),负责消费消息,一般是后台系统负责异步消费。生产者行为模式单一,而消费者根据消费方式的不同有一些特定的分类,常见的有推送型消费者(Push Consumer)和拉取型消费者(Pull Consumer),推送指的是应用系统向Consumer对象注册一个Listener接口并通过回调 Listener 接口方法实现消费消息,而在拉取方式下应用系统通常主动调用消费者的拉消息方法消费消息,主动权由应用系统控制。

3. 消息总线

消息总线(Message Bus)的理论基础是消息驱动的编程方法和计算机硬件总线概念。系统组件之间通过消息总线来进行通信,可以支持组件的分布式存储和并发运行。消息总线是系统的连接件,负责消息的分派、传递和过滤,并返回处理结果。

消息总线风格可以视为分布式消息传递风格的一种扩展和延伸。系统组件并不严格区分客户端和服务器端,组件之间也不是通过消息通道进行直接交互,而是挂接在消息总线上,向总线登记自己所感兴趣的消息类型。生产者组件发出请求消息,然后总线把请求消息分派到系统中所有对此感兴趣的消费者组件,在接收到请求消息后,消费者组件将根据自身状态对其进行响应,并通过总线返回处理结果。由于组件是通过消息总线进行连接的,不要求各个组件具有相同的地址空间,也不要求各个组件采用相同的技术体系和实现机制(见下图),而是提供统一入口,简化数据拦截成本。

在组件之间,消息是唯一的通信方式。根据需要,消息总线对消息具备丰富的预处理功能,包括消息路由(Routing)、消息转换(Transformation)和消息过滤(Filtering)。这些预处理功能消除了数据传递在时间、空间和技术上的耦合,并提供了高度扩展性,但同时也为系统的设计和实现带来了不可避免的复杂度。

4. 分布式风格应用

消息传递、消息总线和Broker这三种分布式风格都在分布式系统架构设计领域有广泛的应用,目前很多主流的分布式框架的背后就是以这三种风格为基础。

(1)Broker

在Broker中,远程服务提供者以某种形式提供服务调用相关信息,远程代理对象通过动态代理拦截机制生成远程服务的本地代理,让远程调用在使用上就如同本地调用一样。而网络通信应该与具体协议无关,通过序列化和反序列化方式对网络传输数据进行有效传输。

在基于分布式环境的交互过程中,远程服务的导入和导出需要遵循特定的业务接口,确保双方在通信语义上的一致。假设我们使用DemoService作为统一业务接口,当进行服务导出时,可以使用如下的代码风格:

在导入服务时有两种基本方式,一种是编译期代码生成,通过在调用前在客户端本地生成桩(Stub)代码即可以在运行时使用桩代码提供的代理访问远程服务,Web Service中通过wsdl生成客户端代码就是这种方式的典型表现;另一种更常见的方式是运行时通过动态代理/字节码的方式动态生成代码。对DemoService服务进行导入的表现形式如下:

针对以上分布式交互的需求,业界提供了一大批优秀的基于Broker思想构建的分布式服务框架,如Alibaba的Dubbo、Facebook的Thrift、Google的Protobuf等。

(2)消息传递

消息传递有两种基本模型,即发布-订阅(Pub-Sub)模型和点对点(Point to Point)模型。发布-订阅支持生产者消费者之间的一对多关系,是典型的推送消费者实现机制;而点对点模型中有且仅由一个消费者,通过拉取或基于间隔性拉取的轮询(Polling)方式进行消息消费。消息持久化是消息传递系统实现存储转发的基本需求,持久化的方式也有多种,可以使用关系型数据库、Key-Value存储容器和文件系统。持久化存储系统还能实现消息堆积,确保在消息发送高峰期挡住数据洪峰,保证后端系统的稳定性。

围绕消息传递业界有一些实现规范和工具,代表性的规范有JMS(代表实现ActiveMQ)和AMQP(代表实现RabbitMQ)。而Kafka、RocketMQ等工具并不遵循特定的规范但也提供了消息传递的设计和实现方案。

(3)消息总线

消息总线的应用主要体现在端点(Endpoint)集成上。在不同的客户端和服务端系统中需要提取专门与消息通道发生直接交互的组件以便于业务模块解耦,这种组件一般就被称为端点。如图4-23中,各种不同的技术体系所实现的客户端应用需要通过中间的消息总线进行交互,那么端点可以用来屏蔽这种技术差异性。

围绕消息总线和端点集成,业界具有代表性的ESB工具有Mule ESB、Apache Camel和Spring Integration。以Spring Integration为例,作为Spring家族中一员以及轻量级、松耦合集成框架,与现有Spring系统完美融合,支持并扩展主流系统集成模式,并提供众多基础性系统交互端点技术。Spring Integration所提供的常见集成端点包括File、FTP、TCP/UDP、HTTP、JDBC、JMS、JPA、Mail、MongoDB、Redis、RMI、Web Services等。

 

如果对文章感兴趣,可以关注我的微信公众号:程序员向架构师转型,或扫描下面的二维码。

我出版了《系统架构设计:程序员向架构师转型之路》、《向技术管理者转型:软件开发人员跨越行业、技术、管理的转型思维与实践》、《微服务设计原理与架构》、《微服务架构实战》等书籍,并翻译有《深入RabbitMQ》和《Spring5响应式编程实战》,欢迎交流

发布了92 篇原创文章 · 获赞 9 · 访问量 11万+

猜你喜欢

转载自blog.csdn.net/lantian08251/article/details/99007602