Broker 模式
使用 Broker 模式可以隐藏远程服务调用的实现细节,方法是将这些细节封装到一个与业务组件自身不同的层 [Buschmann96]。
这个层为客户端提供一个接口,使客户端可以像调用任何本地接口一样调用方法。但是,客户端接口内的方法会触发要对远程对象执行的服务。这对客户端是透明的,因为远程服务对象实现了相同的接口。该模式将启动远程服务调用的业务组件当作"客户端",而将响应远程服务调用的组件当作"服务器"。
图 1 显示没有进行任何分布的简单示例的静态结构。客户端直接调用服务器上的 performFunctionA 方法。仅当服务器对象与客户端对象驻留在同一台计算机上时,才能发生这种情况。
图 2 显示实现分布后的静态结构。
ServiceInterface 是一个必需的抽象,对于在服务器端不必公开实现细节的情况下将由服务器提供的服务来说,这样的抽象可以通过提供有关该服务的和约而使分布成为可能。在实现分布时,将添加客户端和服务器代理,以处理通过网络将方法调用及其参数发送到服务器,然后将响应发回客户端的所有传送工作。代理将完成所有数据封送和拆收、安全控制、传输通道配置和任何其他附加工作。客户端只需调用客户端代理的 performFunctionA 方法,就像它是本地调用一样,这是因为客户端代理实际上实现的是ServerInterface。对客户端进行的代码更改将是最低限度的,因此您可以开发整个业务域模型,而不必知道系统是否是分布式的。对远程服务调用的实现方式的任何更改都将被限制在代理类以内,并且不会对域模型产生任何影响。图 3 显示这些组件之间的一种交互方案。
服务器查找
Broker 解决方案所针对的是前面所述的大多数问题。但是,因为客户端代理直接与服务器代理进行通信,所以客户端必须能够在编译时找到服务器的位置。这意味着,您不能在运行时将服务器更改或移动到不同位置。要克服这一限制,需要避免公开服务器的确切位置。而应当将新组件(即代理程序组件)部署在一个众所周知的位置,然后向客户端公开该位置。此后,代理程序组件负责为客户端查找服务器。代理程序组件还会实现一个用于添加和删除服务器组件的储存库,这样就有可能在运行时添加、删除或交换服务器组件。图 4 显示包含代理程序组件的静态结构。
这种类型的功能通常称为"名称服务"。查找远程对象是企业计算中的一项常见要求。因此,许多平台实现了名称服务,例如,Microsoft 使用 Active Directory® 目录服务。
代理程序驻留在一个不应该频繁更改的、众所周知的位置。已被激活并且准备接收请求的任何服务器都将向代理程序注册自己,以便下一次客户端向代理程序请求这种类型的服务器时,代理程序能够使用它。这还可能提高系统的性能和可用性,因为它使您可以拥有多个同时运行并服务于多个客户端的、完全相同的服务器组件。这种机制有时称为负载平衡。图 5 显示了一个这些组件之间的交互方案示例。
代理程序作为中介
在前面的方案中,代理程序仅负责为客户端查找服务器。这种方案中,客户端从代理程序获得服务器的位置,然后在不涉及代理程序的情况下直接与服务器进行通信。但是,在某些情况下,我们并不希望客户端与服务器之间进行直接通信。例如,由于安全原因,您可能希望将所有服务器放在位于防火墙后面的公司专用网络中,并且只允许代理程序访问它们。这种情况下,您必须让代理程序转发服务器和客户端这二者之间的所有请求和响应,而不是让它们直接相互通信。图 6 显示将此模型修订后的静态结构。
图 7 显示用作客户端和服务器之间的信使的代理程序的交互图。此示例还说明了客户端和服务器之间的通信可以是异步的(注意 sendRequest 调用上的开放箭头)。
也存在这样的情况:客户端必须对同一服务器进行一系列方法调用,才能完成一个持续时间长而且复杂的业务事务。在这样的情况中,服务器必须在前后客户端调用之间保持状态不变。然后,代理程序必须确保客户端在基本会话内所进行的所有服务器调用都会被路由到完全相同的服务器组件。
示例
Broker 模式及其变体在许多分布式系统框架中得到实现。请参阅使用服务器激活对象通过 .NET Remoting 实现 Broker 和使用客户端激活对象通过 .NET Remoting 实现 Broker。
结果上下文
Broker 模式具有 Layered Application 模式的许多优点和缺点。
优点
Broker 具有下列优点:
-
隔离。通过将所有与通信有关的代码分离到它自己的层中,从而使其与应用程序隔离。您可以决定在不必更改任何应用程序代码的情况下以分布方式运行应用程序,或者在一台计算机上运行全部应用程序。
-
简单。将复杂的通信逻辑封装到单独的层中,可以使问题变得更简单。为代理程序编写代码的工程师不必关心无法预知的用户要求和业务逻辑,而应用程序开发人员也不必关心多播协议和 TCP/IP 路由。
-
灵活。通过将多个函数封装在一个层中,可以允许您以不同的实现来交换该层。例如,您可以从 DCOM 切换到 .NET Remoting,再切换到标准 Web Service,而不用更改应用程序代码。
缺点
可惜的是,抽象层可以损害性能。基本规则是,拥有的信息越多,就可以优化得越好。使用单独的代理程序层可能隐藏有关应用程序如何使用较低层的细节,这可能又会阻止较低层执行特定的优化操作。例如,使用 TCP/IP 时,路由协议不知道正在路由的是什么数据包。因此,很难决定包含视频流的数据包(例如)应该具有比包含垃圾邮件的数据包更高的路由优先级。
安全考虑事项
包含敏感业务数据的服务器组件通常位于公司的专用网络中,并受到防火墙的保护。而代理程序位于外围网络(也称为非管制区 (DMZ) 或屏蔽子网)中,外围网络是作为公司专用网络与外部公用网络之间的中性区域而插入的小型网络。只允许从外围网络访问服务器组件,而不允许从外部公用网络访问这些组件。这一额外的网络层阻止了外部用户直接访问服务器。
相关模式
有关 Broker 的详细信息,请参阅下列相关模式:
-
使用服务器激活对象通过 .NET Remoting 实现 Broker 和使用客户端激活对象通过 .NET Remoting 实现 Broker 说明了 Broker 模式的两种实现策略。
-
Remote Proxy 。此模式中所述的 ClientProxy 对象遵循在 [Gamma95,Buschmann96] 中所述的 Proxy 模式的变体(它称为 Remote Proxy)。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)