Azure 服务总线提供两个Java客户端库:
- azure-servicebus-jms - 基于 Apache Qpid JMS 构建的 JMS 2.0 提供程序,支持标准 JMS API 访问服务总线。
- azure-messaging-servicebus - 对服务总线功能具有完全访问权限的本机Azure SDK客户端。
这两个库都通过 AMQP 1.0 连接到服务总线,并支持Microsoft Entra ID身份验证。 它们在功能覆盖范围、层要求和编程模型中有所不同。 选择错误的库会导致需要返工,这意味着只有在开发应用程序后才会发现其限制。 本指南可帮助你在开始之前选取正确的库。
何时使用 JMS
在以下情况下使用 azure-servicebus-jms:
从另一个 JMS 代理迁移。 如果工作负荷当前使用 JMS 插件针对 ActiveMQ、IBM MQ 或 RabbitMQ 运行,则 JMS 库允许你通过最少的代码更改重新指向 服务总线。 JMS 2.0 API 保持不变 - 仅连接工厂配置发生更改。
将 Spring Boot 与 JMS 配合使用。 spring-cloud-azure-starter-servicebus-jms starter 直接与 Spring 的
@JmsListener和JmsTemplate模式集成。 如果你的团队已经利用 Spring 的 JMS 抽象,这是最短的路径。要求符合 JMS 2.0 标准。 某些企业体系结构强制使用标准消息传送 API。 JMS 库在连接到下面服务总线时满足该要求。
利用现有的 JMS 专业知识。 如果开发人员具有深厚的 JMS 体验且没有Azure SDK体验,则 JMS 库的学习曲线较低。
Important
JMS 库需要 Azure 服务总线 高级层才能获得完整的 JMS 2.0 支持。 标准层仅支持具有缩减功能集的 JMS 1.1。 有关详细信息,请参阅 使用 Azure 服务总线 Premium Java 消息服务 2.0 API。
何时使用本机 SDK
在需要时使用 azure-messaging-servicebus :
全面功能使用权限。 本地 SDK 展示了每个 服务总线 的功能:会话(FIFO 排序)、计划消息、消息递延、带有自定义原因和描述的死信处理、批处理操作、跨实体的事务,以及基于序列号的接收。 代码和服务之间没有抽象层。
会话(FIFO 处理)。 JMS API 不支持从启用会话的队列或主题接收消息。 如果工作负荷需要每个会话的有序处理,则本机 SDK 是唯一选项。
基于 WebSocket 的 AMQP。 本机 SDK 支持 WebSocket 传输(端口 443),这在防火墙或公司代理阻止 AMQP 端口 5671 时至关重要。 JMS 库不公开此功能。
标准等级 本地 SDK 在标准层和高级层上的工作方式相同。 标准层上的客户在没有层限制的情况下获得相同的功能集。
异步或响应式模式。 本机 SDK 提供真正的非阻塞式响应式流(Project Reactor
Mono/Flux)。 JMS 支持通过MessageListener基于回调的异步接收,但底层线程模型是阻塞的。 对于需要背压或响应式组合的工作负载,本机 SDK 是更好的选择。细粒度控制。 原生 SDK 可以完全控制预提取计数、连接管理、批处理和锁定续订,以便能够针对特定工作负荷优化性能。 JMS 库将这些功能封装在 JMS 抽象层之后,进行有限的调整。
没有 JMS 依赖项的新项目。 如果没有要保留的现有 JMS 代码库,则本机 SDK 是更好的默认值。 它具有更广泛的功能支持,并与服务更紧密地保持一致。
功能对比
下表比较了每个库的功能:
| Feature | JMS (azure-servicebus-jms) |
本机 SDK (azure-messaging-servicebus) |
|---|---|---|
| 发送和接收消息 | 是的 | 是的 |
| 主题和订阅 | 是的 | 是的 |
| 会话(FIFO) | 否 | 是的 |
| 死信队列 | 部分 - 仅接收,无自定义原因 | 是 - 原因和说明 |
| 预定消息 | 是的- setDeliveryDelay |
是的- scheduleMessage |
| 消息延迟 | 部分 - 仅通过 AMQP 处置 | 是 - 可编程接口 API |
| 批量接收 | 否 | 是的 |
| 基于 WebSocket 的 AMQP | 否 | 是的 |
| 标准级别 | 仅限 JMS 1.1(有限) | 是 - 完整功能集 |
| 高级层 | 是 - JMS 2.0 | 是的 |
| Spring Boot 集成 | 是 - 通过启动器 | 通过 Spring 集成 |
| Microsoft Entra ID | 是的 | 是的 |
| 跨实体事务 | 是的 | 是的 |
| 锁续期 | 手动 | 自动(处理器) |
| 预提取控制 | Limited | 完整 |
| 队列浏览器 | 是的 | 是 - 通过预览 |
| 消息选择器/筛选器 | 部分支持 - 没有LIKE支持 |
是 - 支持 LIKE 的 SQL 筛选器 |
| 临时队列/主题 | 是的 | 无 |
Note
有关Azure 服务总线支持的 JMS 功能的完整列表,请参阅 JMS 功能。
功能详细信息
以下各节介绍了表中影响最大的差异。
会话
JMS API 无法从启用会话的队列或主题接收消息 - JMS 开发人员指南 会明确记录这一点。 没有解决方法。 如果负载需要通过会话实现 FIFO 排序,请使用本机 SDK。
死信
JMS 可以通过 AMQP REJECTED 处置死信消息,但 JMS API 无法设置自定义死信原因或说明。 本机 SDK 的 deadLetter 方法允许您同时指定这两者,这样就可以对死信消息进行分类和优先处理,而无需猜测它们失败的原因。
消息延迟
底层 AMQP 协议将MODIFIED_FAILED_UNDELIVERABLE映射到Defer(),因此您可以通过 JMS 库的 AMQP 层推迟消息的处理。 但是,没有用于按序列号延迟或接收已延迟消息的程序化 JMS API。 此限制使得大多数实际工作负荷的延迟不切实际。
WebSocket 传输
JMS 库的连接工厂在端口 5671 上生成 amqps:// URI(基于 TLS 的 AMQP)。 WebSocket 传输无法通过标准配置路径来使用。 如果网络阻止端口 5671,则无法使用 JMS 库。 本机 SDK 在端口 443 上通过 WebSocket 支持 AMQP。
常见迁移方案
从ActiveMQ到服务总线
使用 JMS。 此方法提供最简单的迁移路径。 现有 JMS 代码基本保持不变 - 将 ActiveMQ 连接工厂替换为 ServiceBusJmsConnectionFactory,更新连接字符串并进行测试。
有关分步指南,请参阅《从 ActiveMQ 迁移到 Azure 服务总线》。
评估 ActiveMQ 工作负荷使用的任何功能是否不受 JMS 库中的支持(请参阅比较表)。 如果应用依赖于会话、WebSocket 传输或批处理接收,请将这些组件迁移到本机 SDK。
IBM MQ 到 服务总线
使用 JMS 处理现有的基于 JMS 的工作负载。 如果 IBM MQ 应用使用 JMS API,则服务总线 JMS 的迁移路径类似于 ActiveMQ - 交换连接工厂和配置。
使用原生 SDK 进行新代码开发。 如果你在重写消息层,本地 SDK 允许你访问完整的 服务总线 功能集,而不受 JMS 的限制。
启动新项目
默认为原生 SDK,除非有特定理由使用 JMS(可移植性要求、现有的 JMS 专业知识或 Spring Boot JMS 启动器集成)。 原生 SDK 具有更广泛的功能覆盖范围,可用于标准层和高级层,并更加与服务保持一致。
JMS 库的已知限制
在选择 JMS 库之前,请查看这些限制。 每个因素都导致客户在项目中途切换到本机 SDK。
无会话支持。 JMS API 无法从启用会话的实体接收。 此限制是最常见的返工任务源之一,客户选择 JMS 构建工作负载,接着却发现需要使用 FIFO 排序,因此必须切换到本机 SDK。
无 WebSocket 传输。 库将
amqps://硬编码为在端口 5671 上通过 TLS 运行的 AMQP。 如果网络阻止该端口,则无法使用 JMS 库。没有带原因的死信。 当 JMS 库通过 AMQP
REJECTED处置将消息标记为死信时,它无法添加自定义原因或描述。 此限制使死信队列会审更加困难。JMS 2.0 所需的高级层。 标准层仅支持具有缩减功能集的 JMS 1.1。 如果成本是一个问题,并且不需要高级版,则本机 SDK 可在标准层上完全工作。
不支持分布式事务(XA/JTA)。 两个库都不支持分布式事务。 两者都支持单个服务总线命名空间中的跨实体事务。
部分消息选择器。 服务总线上的 JMS 消息选择器不支持
LIKE模式匹配。 本机 SDK 使用不同的筛选机制(订阅规则),该机制支持LIKE。