2013-07-09 74 views
3

這是我遇到的問題,與設計和實現相關:啓動後臺任務的同步Jersey Rest服務?

我有一個接受POST請求的REST Web服務。沒什麼特別的。它目前同步響應。

但是,該Web服務將啓動可能需要很長時間的後臺進程。

我不希望此服務在30分鐘後回覆。

相反,它應該立即返回一個ack響應給客戶端,沒有什麼更多(即使在30分鐘後,將不會有更多的信息發送)。

我如何在Jersey中實現這樣的行爲?

我看了https://jersey.java.net/nonav/documentation/2.0/async.html#d0e6914頁面。

雖然這是一個有趣的閱讀,但我沒有找到方法來發送ACK類型的響應(類似於HTTP 200代碼)。

也許我很混淆異步和我想實現的行爲。

我只是明白,我可以在我的@POST方法中創建一個新的線程來處理後臺進程,並立即返回ACK響應。

但是這個新線程在響應被髮送回客戶端之後是否生效?

你將如何實現這個WS?

我希望你能幫我澄清這一點。

+0

爲什麼你的線程不會活着?我只會產生一個新的線程,因爲這個線程的結果並不涉及客戶端。 – condit

+0

@condit:我嘗試了這種方法:它效果很好。我們將在第一次迭代中堅持使用它,但我確信每次調用WS時都會創建一個新線程會導致一些問題,對吧? – jeromedt

+0

你不應該直接創建線程。你會想用一個'Executor'來創建一個線程池。您可以從一個固定大小的線程池開始,並將其調整到您的應用程序。 – condit

回答

4

我認爲你鏈接的澤西島2異步服務器API仍然會保持客戶端連接,直到處理完成。異步處理對澤西來說真的是內部的,並且不影響客戶體驗。

如果你想返回一個ACK,你可以使用普通的Jersey方法,將工作委託給另一個線程,然後立即返回。我建議使用HTTP 202作爲這個用例。

您可以創建一個線程來這樣做就像在新澤西州2例,它會生存的球衣資源方法調用的執行:

@POST 
public Response asyncPost(String data) { 
    new Thread(...).start(); 
    return Response.status(Response.Status.ACCEPTED).build(); 
} 

這就是說,創建線程一般不推薦內應用服務器。

如果您使用EE7,我建議你看看JSR-236 http://docs.oracle.com/javaee/7/api/javax/enterprise/concurrent/package-summary.html

如果您使用EE6,可以考慮將消息發送到隊列被處理的消息驅動豆(MDB)在背景中。

+0

感謝您的回覆。我在澤西島內使用異步程序時有點困惑。你的回答讓我明白這對澤西來說完全是內在的。我昨天晚上嘗試了一個示例代碼,它在WS Jersey中啓動了一個新線程:它完美地工作。但是,您指出應用程序服務器中不建議使用線程。我們正在使用Tomcat 6,而不是完整的符合JEE的服務器。你也建議MDB實現:JMS是一個可行的解決方案嗎?再次感謝您的時間和您的明確解釋。我會研究你提供的鏈接。 – jeromedt

+0

JMS可以工作(假設消耗線程被合併),這就是MDB構建在其上的東西,但JMS也不是EE Web配置文件的一部分,所以你可能不能在Tomcat 6中使用它,除非你有一個可用的外部MQ產品。如果您無法升級到EE,我建議至少使用http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ExecutorService.html。儘管它仍然會在容器的權限之外創建線程,但至少它會爲您提供一個通過Futures爲任務提供池化和異步處理的框架。 – TheArchitect

+0

的確,我的問題也得到了同樣的答覆。感謝您提供的所有細節。祝你有美好的一天。 – jeromedt