Spring JMS 模板 - 并发调用

Spring JMS Template - Concurrent Calls

我可以使用 Spring JMSTemplate 进行并发呼叫吗?

我想并行调用 4 个外部服务,我正在探索使用 Spring 的 JMSTemplate 并行执行这些调用并等待执行完成。

我正在考虑的另一个选项是使用 ExecutorService

使用一个比另一个有什么优势吗?

JMSTemplate 是线程安全的,因此对其进行并行调用不是问题。

消息服务对于大多数任务来说通常足够快,并且可以以最小的延迟接收您的消息,因此添加 ExecutorService 似乎不是您通常需要的第一件事。您真正需要的是正确配置您的 JMS 连接池并为其提供足够的开放连接(在您的情况下为四个),以便它可以无阻塞地处理您的并行请求。

您只需要 ExecutorService 以防您不关心有保证的交付并且您的程序需要极高的速度而您的消息服务无法提供,这是极不可能的。

至于从您的外部服务接收回复,您需要使用 JMS Request/Reply pattern (you can find examples in this article). Happily, as you're using Spring, you could make Spring Integration do lots of work for you. You need to configure outbound-gateway to send messages and inbound-gateway to receive responses. Since version 2.2 you can also use reply-listener to simplify things on your client side. All these components are covered in the official documentation(也有示例)。

因此需要使用异步方法与两个以上的 JMS 队列(发送和/或接收)并行通信。最好的选择是在方法级别使用 @Asynch

此示例包含 RestTemplate ,但在您的情况下创建 JmsTemplate bean。

先决条件:- 请创建适当的 JMS Bean 以连接到队列。正确使用这将有助于并行调用两个队列。它肯定有效,因为我已经实施了。由于版权问题,我只提供骨架。

更多详细信息:Spring 引导 + Spring 异步 https://spring.io/guides/gs/async-method/

步骤 1:创建服务 Class,其中 JMS 队列

@EnableAsynch
public class JMSApplication {

@Autowired
JmsService jmsService;

     public void invokeMe(){
      // Start the clock
        long start = System.currentTimeMillis();

        // Kick of multiple, asynchronous lookups
        Future<Object> queue1= jmsService.findqueue1();
        Future<Object> queue2= jmsService.findqueue2();

        // Wait until they are all done
        while (!(queue1.isDone() && queue2.isDone())) {
            Thread.sleep(10); //10-millisecond pause between each check
        }

        // Print results, including elapsed time
        System.out.println("Elapsed time: " + (System.currentTimeMillis() - start));
        System.out.println(queue1.get());
        System.out.println(queue2.get());

     }
}

第二步:编写包含业务逻辑的服务方法 对于 Jms

   @Service
   public Class JmsService{

         @Asynch
         public Object findqueue1(){
         //Logic to invoke the JMS queue 
         }

         @Asynch
         public Object findqueue2(){
         //Logic to invoke the JMS queue 
         }
    }