我可以使用Spring的JMSTemplate
进行并发调用吗?
我想要同时进行4个外部服务调用,正在探索使用Spring的JMSTemplate
来实现这些并行调用并等待执行完成。
另一个选择是使用ExecutorService
。
使用其中一个是否有优势?
我可以使用Spring的JMSTemplate
进行并发调用吗?
我想要同时进行4个外部服务调用,正在探索使用Spring的JMSTemplate
来实现这些并行调用并等待执行完成。
另一个选择是使用ExecutorService
。
使用其中一个是否有优势?
JMSTemplate
是线程安全的,因此对它进行并行调用不是问题。
对于大多数任务来说,消息服务通常足够快,并且可以以最小的延迟接收您的消息,因此添加ExecutorService
似乎不是您通常需要的第一件事。您真正需要做的是正确配置JMS连接池并提供足够的开放连接(在您的情况下为四个),以便它可以处理您的并行请求而不会阻塞。
只有在您不关心保证交付并且您的程序需要极高的速度时,才需要使用ExecutorService
,而您的消息服务无法提供这种速度,这种情况非常罕见。
至于从外部服务接收回复,您需要使用JMS请求/响应模式(您可以在本文中找到示例)。幸运的是,由于您正在使用Spring,您可以让Spring Integration为您完成大量工作。您需要配置outbound-gateway
以发送消息和inbound-gateway
以接收响应。自2.2版本以来,您还可以使用reply-listener
来简化客户端方面的事情。所有这些组件都在官方文档中涵盖(也包括示例)。
RemoteService
),其中包含一个名为 request(...)
的方法,该方法将请求发送到服务器,并创建一个 Future
,然后将其放入某个本地映射(并发映射)中,以消息 ID 作为键,将此 Future
返回给调用方,然后异步等待来自服务器的响应。一旦响应到达,只需在映射中找到相应的 Future
(使用响应的关联 ID),并为其分配一个值。 - Andrew Lygin需要使用异步方法与两个以上的JMS队列(发送和/或接收)进行通信。最佳选择是在方法级别使用@Asynch。
此示例包含RestTemplate,但在您的情况下,请创建JmsTemplate bean。
先决条件:请创建适当的JMS Bean以连接到队列。正确使用此功能将有助于并行调用两个队列。我已经实施过,所以它肯定有效。由于版权问题,我只提供了框架代码。
更多细节:Spring Boot + Spring Asynch https://spring.io/guides/gs/async-method/
步骤1:创建一个服务类,在该类中定义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());
}
}
@Service
public Class JmsService{
@Asynch
public Object findqueue1(){
//Logic to invoke the JMS queue
}
@Asynch
public Object findqueue2(){
//Logic to invoke the JMS queue
}
}