我可以使用Spring JMSTemplate
进行并发调用吗?
我想并行进行4次外部服务调用,并且正在探索使用Spring的JMSTemplate
并行执行这些调用并等待执行完成。
我正在考虑的另一个选择是使用ExecutorService
。
使用一个优于另一个是否有任何优势?
答案 0 :(得分:2)
JMSTemplate
是线程安全的,因此对它进行并行调用不是问题。
对于大多数任务,消息传递服务通常足够快,并且可以以最小的延迟接收您的消息,因此添加ExecutorService
似乎不是您通常需要的第一件事。您真正需要的是正确配置JMS连接池并为其提供足够的开放连接(在您的情况下为四个),以便它可以无阻塞地处理您的并行请求。
如果您不关心保证投放,您只需要ExecutorService
,并且您的计划需要极高的速度,而您的邮件服务无法提供,这种可能性极低。
至于从外部服务接收回复,您需要使用JMS Request/Reply pattern(您可以在本文中找到示例)。令人高兴的是,当你使用Spring时,你可以让Spring Integration为你做很多工作。您需要配置outbound-gateway
来发送消息,并inbound-gateway
来接收回复。从版本2.2开始,您还可以使用reply-listener
来简化客户端的操作。所有这些组件都包含在the official documentation中(也有示例)。
答案 1 :(得分:2)
因此需要使用异步方法与两个以上的JMS队列(发送和/或接收)并行进行通信。最佳选择是方法级别的@Asynch
此示例包含RestTemplate,但在您的情况下创建JmsTemplate bean。
先决条件: - 请创建适当的JMS Bean以连接到队列。正确使用这将有助于调用两个队列paralleley。它的确有效,因为我已经实施了。由于版权问题,我只是给了骨架。
更多细节:Spring Boot + Spring Asynch https://spring.io/guides/gs/async-method/
步骤1:创建JMS队列
的服务类 @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());
}
}
步骤2:编写将包含业务逻辑的服务方法 对于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
}
}