2009-12-02 62 views
2

我們使用axis2來構建我們的Web服務和一個Jboss服務器來運行我們所有應用程序的邏輯。我們被要求構建一個Web服務,與一個可能需要1小時響應的Bean進行對話(取決於請求的大小),因此我們無法保持與在此期間打開的使用者的連接。長時間運行的webservice體系結構

我們可以使用一個異步web服務,但這並不是很出色,所以我們決定我們可以實現一個bean,它將執行web服務背後的邏輯,並讓服務異步調用該bean。 Web服務將生成一個令牌傳遞給消費者,消費者可以使用它來查詢請求的狀態。

我的問題是:

  1. 如何查詢我的JBoss服務器上的bean的狀態,一旦我從在創建的bean中的服務方法返回。我需要使用有狀態的bean嗎?
  2. 如果我想從web服務端進行異步調用,我可以使用有狀態bean嗎?

回答

1

我不認爲有狀態會話bean是您的問題的答案,它們被設計用於長時間運行的會話會話,這不是您的場景。

我的建議是使用Java5的風格ExecutorService線程池,創建使用Executors工廠類:

  1. 當Web服務服務器初始化,創建一個ExecutorService實例。
  2. Web服務調用進來後,處理程序創建一個Callable的實例。 Callable.call()方法將以業務邏輯bean的形式進行實際調用,無論採用何種形式。
  3. 這個Callable傳遞給ExecutorService.submit(),它立即返回一個Future對象,表示最終的調用結果。 Executor將開始在單獨的線程中調用您的Callable
  4. 生成隨機令牌,將Future存儲在Map中,令牌爲密鑰。
  5. 返回令牌的Web服務客戶端(步驟1到4,應立即發生)
  6. 後來,他的Web服務客戶端發出另一個呼叫請求的結果,傳遞令牌
  7. 的服務器查找Future使用令牌,並使用超時值在Future上調用get(),以便它只等待答案的短時間。調用get()將返回調用的任何Callable的執行結果。
    • 如果答案可用,請將其返回給客戶端,並從「映射」中刪除Future
    • 否則,請告訴客戶稍後再回來。

這是一個非常強大的方法。如果您願意,您甚至可以配置ExecutorService來限制可以同時執行的呼叫數。

+0

這似乎是一個新的線程創建時,我使用此接口。我嘗試創建一個簡單的線程,並嘗試了Timer,然後遇到了另一個問題。當子線程執行時,它似乎無法訪問.aar文件中定義的數據類型。我的自定義數據類型都不被識別,我必須將它們放在tomcat lib文件夾中的一個單獨的jar中才能使用。我認爲在這裏會發生同樣的情況......你知道是否有解決方法,所以我不必把這個jar放在tomcat lib目錄中? 謝謝 – poijoi 2009-12-03 00:34:16

+0

另外如何將令牌保存在Map中?當方法返回對web服務客戶端的響應時,該對象將會死亡...否? – poijoi 2009-12-03 00:41:24

3

你可以採取的另一種方法是利用JMS和數據庫。

的過程會是

  1. 在Web服務調用,把消息放在JMS隊列
  2. 插入一條記錄到數據庫中的表,以及該記錄返回一個唯一的ID給客戶
  3. 在偵聽隊列的MDB,叫豆
  4. 當豆收益,具有「完成」狀態
  5. 當客戶端調用的狀態,讀取數據庫記錄,返回「未完成更新數據庫記錄「或」完成「正在等待記錄。
  6. 當客戶端調用,並記錄顯示「完成」,返回「完成」,並刪除記錄

這個過程是對資源的使用更重了一點,但有一定的優勢

  • 一如果你的bean方法拋出異常
  • 如果你的服務器重新啓動
  • 通過使用數據庫表,而不是一些靜態數據的持久JMS隊列會重新傳遞一個持久的JMS隊列會重新傳遞,可以支持羣集或加載BAL anced環境