2

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

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

我正在查看的另一个选项是使用ExecutorService.

使用其中一个有什么优势吗?

4

2 回答 2

5

JMSTemplate是线程安全的,所以对它进行并行调用不是问题。

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

您只需要ExecutorService在您不关心有保证的交付并且您的程序需要您的消息服务无法交付的极高速度的情况下才需要,这是极不可能的。

至于从外部服务接收回复,您需要使用JMS 请求/回复模式(您可以在本文中找到示例)。令人高兴的是,当您使用 Spring 时,您可以让 Spring Integration 为您做很多工作。您需要配置outbound-gateway发送消息和inbound-gateway接收响应。从 2.2 版开始,您还可以使用它reply-listener来简化客户端的操作。所有这些组件都包含在官方文档中(以及示例)。

于 2016-07-01T05:25:20.860 回答
3

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

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

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

更多细节:Spring Boot + Spring 异步 https://spring.io/guides/gs/async-method/

Step1:在JMS Queue中创建一个服务类

@EnableAsynch
公共类 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());

     }
}

Step2:编写包含Jms业务逻辑的Service Method

   @Service
   public Class JmsService{

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

         @Asynch
         public Object findqueue2(){
         //Logic to invoke the JMS queue 
         }
    }
于 2016-07-01T08:44:11.943 回答