2011-12-22 49 views
0

我有一個Web應用程序,它接收用戶請求並將它們放入MYSQL數據庫中。現在,典型的用戶請求需要按照需要大量時間才能完成的工作流程進行服務。爲了解決這個問題,我有一個不斷監聽MYSQL表的異步處理器。在Java中觸發異步進程

我注意到,在無限循環上輪詢MYSQL表會導致我的應用程序部署到的盒子上的CPU使用率激增,這往往會導致該盒子無法使用。

我知道,在MYSQL數據庫中沒有任何活動請求的情況下,讓異步進程在'某些'時間休眠是一種選擇,但是我想保留這個作爲最後的手段。

由於涉及服務單個請求的工作流程需要時間,並且還需要將處理從前端解耦以允許後端發展,因此使此過程處於同步狀態不是一種選擇。

我想知道是否有任何智能的方法來觸發異步進程,以便我可以避免CPU使用率峯值並仍然從異步處理器獲得最佳響應時間。

任何意見,將不勝感激。

感謝 p1ng

+1

您構思此問題的方式表明您有兩個單獨的應用程序。是否有理由不能有一個多線程的Web應用程序異步處理剛插入數據庫的數據? – Carth 2011-12-22 16:15:34

+0

對於所有實際用途,前端和後端可以被視爲不同的應用程序。我無法採用多線程方式的原因是因爲處理每個請求所涉及的工作流利用了單數且無線程的資源,並且我不希望在每個請求的基礎上阻止這些資源。此外,異步處理器仍在不斷髮展,對解耦的需求也是因爲我們計劃在將來爲外部API調用打開它。 – ping 2011-12-22 16:23:28

+0

你能詳細說明爲什麼你會得到一個CPU使用率高峯嗎?除了使後端多線程,我不明白爲什麼你有一個問題,你可以做什麼。 – 2011-12-22 16:33:56

回答

1

的選擇是存儲在數據庫中的請求,並在你的系統發送某個事件(例如JMS消息,或使用的java.util.concurrent結構)。讀取和執行命令的過程可以被這個信號喚醒,然後像往常一樣去獲取數據庫中的數據並對其進行處理。

這樣,您不會浪費CPU週期輪詢尚未提供的數據,並且由於沒有輪詢延遲,您會更加反應。

+0

謝謝,JMS是我打算採取的路徑。 – ping 2011-12-26 08:36:41

1

您可以使您的異步進程從TCP套接字或類似的東西中讀取。異步進程應該等待I/O阻塞。然後,在主進程中,一旦更新了表,您就可以將消息發送到異步進程。也可以從數據庫中的觸發器發送消息。

+0

這很有趣。你將如何從觸發器發送消息?你有一個例子或鏈接? – perissf 2011-12-22 16:39:15

+0

@perissf以下鏈接表明它可能是可行的http://dev.mysql.com/doc/refman/5.0/zh/faqs-triggers.html#qandaitem-B-5-1-10 – 2011-12-22 16:48:51

1

我通常不會推薦使用基於輪詢的方法來檢查表格。當你必須在不同的時間表輪詢不同的事件時會發生什麼?如果您預計將來需要多個事件,我會建議查看消息隊列以獲取異步任務。

但是,如果你現在必須採用基於輪詢的方法 - 我不完全理解你的理由,不讓異步進程休眠一段時間?爲什麼你想讓你的進程消耗所有的CPU資源,而無所事事,只能在無限循環中運行?爲什麼不讓異步進程按特定間隔運行?您可以使此輪詢間隔可配置。

1

您可以使用FutureTask Java API來做到這一點。見that blog entry

或者也許只是new Thread(YourRunnable).start(),並在YourRunnable中做一些狀態變量來知道你的任務是否完成。