无需确认即可实现 Spring JMSTemplate

问题描述

我们有一个需求是构建 spring boot 命令行应用程序,我们必须将消息发送到队列。

只设置了请求队列。 由于没有设置响应队列,无论客户端是否收到消息,我们都不会从客户端获得任何确认。 现在我正在使用 Spring 的 jmstemplate send() 方法将消息发送到请求队列和 SingleConnectionFactory 来创建一个共享连接,因为这是命令行应用程序

由于我们发送到请求队列的消息没有确认/响应,端到端测试很困难。 如果获得目标/请求队列连接,并且消息无异常发送,我认为测试成功。

仅实现 Spring JMS 模板的 send() 方法是否正确?并且不遵循 jms 模板发送/接收模式

注意:无法设置响应队列并从客户端获得任何确认。

解决方法

在 JMS(以及大多数其他消息传递系统)中,生产者和消费者在逻辑上是分开的(即解耦)。这是系统基本设计的一部分,旨在降低复杂性并提高可扩展性。有了这些限制,你的生产者不应该关心消息是否被消费。生产者只是发送消息。同样,消费者不应该关心谁发送消息或发送的频率等。他们的工作只是消费消息。

假设您的应用程序实际上正在对消息做一些事情(即存在某种消息处理的功能输出),那么这就是您的端到端测试应该测量的内容。如果您得到了您正在寻找的最终结果,那么您可能会推断出中间的步骤(例如发送消息、接收消息等)已成功完成。

需要明确的是,使用 Spring 的 JMSTemplate 发送消息而不使用请求/响应模式是完全可以的。一般来说,如果您没有出现异常,则表示消息已成功发送。但是,在使用 JMSTemplate 时还有其他注意事项。例如,Spring's JavaDoc 是这样说的:

与此模板一起使用的 ConnectionFactory 应返回池连接(或单个共享连接)以及池会话和消息生产者。否则,临时 JMS 操作的性能将会受到影响。

也就是说,了解您的特定 JMS 客户端实现的行为很重要。许多实现将异步发送非持久性 JMS 消息(即即发即忘),这意味着它们可能无法到达代理并且不会在客户端上抛出异常。发送持久消息通常足以保证客户端在出现任何问题时会抛出异常,但请参阅您的客户端实现文档以进行确认。