本文介绍消息传送桥模式,这种技术可用于集成构建在不同消息传送基础结构之上的不同系统。
上下文和问题
许多组织和工作负荷可能会无意中拥有使用多种消息传送基础结构(例如 Microsoft 消息队列 (MSMQ)、RabbitMQ、Azure 服务总线和 Amazon SQS)的 IT 系统。 之所以发生此问题,可能是因为合并和收购,也可能是因为将当前的本地系统扩展到云托管组件以增强成本效益和易于维护性。
开发人员可以通过修改集成的系统以使用基于 HTTP 的 Web 服务进行通信来解决这一难题。 但是,这种方法有缺点,其中包括:
- 必须通过在一侧添加 HTTP 客户端并在另一侧添加 HTTP 请求处理程序来修改系统。 然后必须重新测试和重新部署系统。
- 必须托管 HTTP 终结点,这会增加因实现 Web 服务的安全性和高可用性而导致的复杂性。
- 频繁出现网络连接问题,需要定制的重试机制。
解决方案
如果正在集成的系统由通过交换消息进行通信的组件组成,则消息传送桥模式可以改进集成并减少缺点。
在这种情况下,每个系统都连接到一个消息传送基础结构。 若要跨消息传送基础结构进行集成,请引入同时连接到两个或以上的消息传送基础结构的桥组件。 桥从其中一个拉取消息并将其推送到另一个,而不更改有效负载。
被集成的系统不需要识别其他系统或桥。 发送方系统被配置为将特定消息发送到其本机消息基础结构上的指定队列。 桥选取消息并将它们转发到另一消息传送基础结构中的另一个队列,由接收器系统接收。
好处
- 通过消息传送桥集成的系统无需进行修改。 理想情况下,终结点不知道消息已桥接。
- 由于存在“至少一次”消息传送机制保证,与 HTTP 替代方案相比,集成更加可靠。
- 迁移方案可以更加灵活。 例如,可以按计划将终结点从一个消息传送基础结构迁移到另一个消息传送基础结构,而不用一次性全部迁移。
缺点
- 桥接路由上可能无法使用一种或两种消息传送技术的高级功能。
- 桥接路由需要考虑两种技术的局限性。 例如,最大消息大小在 MSMQ 中可能为 4 MB,但在 Azure 存储队列中仅为 64 KB。
问题和注意事项
在实现消息传送桥模式时,请考虑以下几点:
如果集成的系统之一依赖于分布式事务(例如 Microsoft 分布式事务处理协调器 (DTC))来保证正确性,则必须在桥中实现重复数据删除机制。
如果集成的系统之一不使用任何消息传送基础结构且无法进行修改,则可在另一个系统使用的基础结构和 SQL Server 模拟队列之间构建消息传送桥。 旧系统可以使用 SQL Server 的变更数据捕获功能来发送消息,将其更改推送到专用队列表中。 桥可以将这些消息转发到实际的消息传送基础结构。
你可以在每个消息传送基础结构中使用单个队列(指定为桥接队列)。 在此拓扑中,将发送系统配置为使用该特定队列作为发送到另一系统的消息类型的目标。 还可以在每个消息传送基础结构中使用多对队列,因此发送方不会感知到桥。 为目标系统的消息传送基础结构中的每个目标队列创建一个影子队列。 桥在影子队列与其对应队列之间转发消息。
为了满足所需的可用性服务级别协议 (SLA),你可能需要使用使用者竞争方法来横向扩展消息传送桥。
常规消息处理组件使用重试模式来处理暂时性故障。 重试计数器限制使组件能够检测有害消息并将其从队列中删除,以解除对处理操作的阻止。 如果发生基础结构故障,桥可能需要不同的重试策略,以防止将消息错误地识别为有害消息。 可以使用断路器模式来暂停转发。
何时使用此模式
需要执行以下操作时,请使用消息传送桥模式:
- 集成现有系统,只需极少量的修改。
- 集成无法使用其他消息传送技术的旧版应用程序。
- 使用云托管组件扩展现有的本地应用程序。
- 当 Internet 连接不稳定时连接地理分布式系统。
- 将单个分布式系统从一个消息传送基础结构增量迁移到另一个消息传送基础结构,无需一次性迁移整个系统。
如果出现以下情况,此模式可能不适用:
- 所涉及的至少一个系统依赖于一个消息传送基础结构的一项功能,而另一个系统则不存在该功能。
- 集成本质上是同步的,发起系统要求即时响应。
- 集成具有特定的功能或非功能要求,例如安全或隐私问题。
- 集成的数据量超出了消息传送系统的容量,或者使消息传送成为一项昂贵的问题解决方案。
工作负载设计
架构师应评估如何在其工作负载的设计中使用“消息传送桥模式”,以解决 Azure Well-Architected Framework 支柱中涵盖的目标和原则。 例如:
支柱 | 此模式如何支持支柱目标 |
---|---|
成本优化的重点是维持和提高工作负载的投资回报率。 | 通过允许与使用不同消息传递或事件处理技术的系统进行互操作,这一中间步骤可以延长现有系统的使用寿命,而无需重写。 - CO:07 组件成本 |
卓越运营有助于通过标准化流程和团队凝聚力来实现工作负荷质量。 | 当在工作负载中转换消息传递和事件处理技术时,或者当有来自外部依赖项的异构需求时,这种分离提供了灵活性。 - OE:06 部署工作负载更改 |
与任何设计决策一样,请考虑对可能采用此模式引入的其他支柱的目标进行权衡。
示例
有一个用 .NET Framework 编写的应用程序,用于管理本地托管的员工调度。 该应用程序结构良好,具有通过 MSMQ 进行通信的单独组件。 该应用程序可以运行,工作负荷团队无意重新编写它。 需要构建调度数据的新使用者来满足业务需求,并且 IT 策略要求将新软件构建为云原生应用程序,以优化成本和交付时间。
基于异步队列的体系结构过去适用于工作负荷团队,因此该团队将使用相同的体系结构方法,但采用新式技术,即服务总线。 工作负荷团队不希望在云部署和本地部署之间引入同步通信以缓解其中一个部署(会影响另一个部署)的延迟或不可用性。
团队决定使用消息传送桥模式来连接两个系统。 该模式由两个部件组成。 一个部件从现有的 MSMQ 队列接收消息并将其转发到服务总线。 另一个部件从服务总线获取消息并将其转发到现有的 MSMQ 队列。
实施团队在使用这种方法时会利用现有应用程序中的现有基础结构来与新组件集成。 现有应用程序不知道新组件托管在 Azure 中。 同样,新组件与旧应用程序的通信方式与它们自己之间的通信方式相同,即发送服务总线消息。 桥在两个系统之间转发消息。
作者
本文由 Microsoft 维护, 它最初是由以下贡献者撰写的。
主要作者:
- Rob Bagby | 主体体系结构内容主管
- Kyle Baley | 软件工程师
- Udi Dahan | Particular Software 创始人兼首席执行官
- Chad Kittel | 首席软件工程师
- Bryan Lamos | 开发者关系
- Szymon Pobiega | 工程师
若要查看非公开领英个人资料,请登录领英。
后续步骤
- 来自企业集成模式社区的消息传送桥模式说明。
- 了解如何在 Spring Java 框架中实现消息传送桥。
- QPid 桥可用于桥接支持 AMQP 的消息传送技术。
- NServiceBus 消息传送桥是队列到队列桥的 .NET 实现,支持一系列消息传送基础结构(包括 MSMQ、服务总线和 Azure 队列存储)。
- NServiceBus.Router 是一个实现消息传送桥模式的开放源代码项目。 它还允许在单个实例中桥接两种以上的技术,并具有高级消息路由功能。