2016-07-01 33 views
1

我可以使用Spring JMSTemplate進行併發呼叫嗎?Spring JMS模板 - 併發調用

我想同時進行4個外部服務調用,並且正在探索使用Spring的JMSTemplate來並行執行這些調用並等待執行完成。

我正在看的其他選項是使用ExecutorService

使用其中一個有什麼優勢嗎?

+0

你想做出不同的JMS隊列或同一隊列並行調用? – Pavan

+0

對於不同的jms隊列,Pavan –

+0

你想同步調用外部服務器還是異步?也就是說,是否要在發送請求並等待響應後阻塞線程(在服務器處理請求之前無法在此線程中執行其他操作)?或者你想要一個線程發出請求並繼續工作(不管它是什麼),同時等待來自服務器的響應嗎? –

回答

2

JMSTemplate是線程安全的,因此對其進行並行調用並不是問題。

消息傳遞服務對於大多數任務來說通常足夠快,並且可以以最小的延遲接收消息,所以添加ExecutorService似乎不是您通常需要的第一件事。你真正需要的是正確配置你的JMS連接池並給它足夠的開放連接(在你的情況下有四個連接),以便它可以處理你的並行請求而不會阻塞。

您只需要ExecutorService以防萬一您不關心保證交付,並且您的程序需要極高的速度讓您的消息傳遞服務無法提供,這是極不可能的。

至於從您的外部服務接收回復,您需要使用JMS Request/Reply pattern(您可以在本文中找到示例)。令人高興的是,當你使用Spring時,你可以讓Spring Integration爲你做很多工作。您需要配置outbound-gateway才能發送消息,並需要配置inbound-gateway才能接收響應。從版本2.2開始,您還可以使用reply-listener來簡化客戶端的操作。所有這些組件都包含在the official documentation中(也有示例)。

+0

謝謝@安德魯。我有可能使用jms並等待接收到響應嗎?過去我使用jms進行異步消息傳遞,但是在這種情況下,我的代碼應該阻塞,直到我得到我所有4個調用的響應。 –

+0

關於連接池,我的服務每分鐘會收到100個請求,所以我相信我應該設置一個更高的連接池,如果我沒有錯誤 –

+0

對於大多數現代消息系統,100s請求/分鐘沒有什麼大不了的(if正確配置)。此外,如果您只使用四個線程發送消息,則不需要更多的連接,因爲它們將處於空閒狀態。但是你需要一些額外的連接來接收回應。讓我們繼續討論你的問題,然後我可以澄清我的答案。 –

2

因此需要使用異步方法與兩個以上的JMS隊列(發送和/或接收)並行通信。最好的選擇是方法級別的usng @Asynch

本示例包含RestTemplate,但在您的情況下創建JmsTemplate bean。

先決條件: - 請創建適當的JMS Bean以連接隊列。正確使用這將有助於調用兩個隊列paralleley。它的作品是肯定的,因爲我已經實施了。由於版權問題,我只是給了骨架。

更多細節:春引導+彈簧非同步 https://spring.io/guides/gs/async-method/

第一步:創建服務類,其中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()); 

    } 
} 

第二步:編寫將包含業務邏輯01的服務方法爲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 
     } 
    } 
+0

謝謝帕文!我也會試試這個,因爲我也使用了spring boot。 –

+0

春季引導!胡!!!!那麼你的工作更容易:) – Pavan

+0

是的!再次感謝Pavan :) –