2008-09-07 62 views
8

在播客#15中,Jeff提到他在關於如何在後臺運行常規事件,好像這是一個正常功能 - 很不幸,我似乎無法通過twitter 。現在我需要做一個類似的事情,並且會把問題提交給羣衆。在Java Web應用程序中運行常規後臺事件

我目前的計劃是當第一個用戶(可能是我)進入網站時,它啓動一個後臺線程,等待分配時間(小時小時),然後開始阻止其他人的事件(我是Windows程序員通過交易,所以我認爲在事件和WaitOnMultipleObjects方面),直到它完成。

Jeff是如何在Asp.Net中完成的,他的方法是否適用於Java Web應用程序世界?

回答

12

我認爲開發運行的後臺任務並不總是值得的定製解決方案,所以我建議使用在Quartz Scheduler Java的。

在您的情況下(需要在Web應用程序中運行後臺任務),您可以使用包含在initialize the engine at the startup of your web container分配中的ServletContextListener。

之後,您有很多可能性來啓動(觸發)您的後臺任務(作業),例如,您可以使用日曆或類似cron的表達式。在你的情況下,你很可能應該用SimpleTrigger來解決,讓你以固定的時間間隔運行工作。

在Quartz中,作業本身也可以很容易地描述,但是你還沒有提供任何關於你需要運行的細節,所以我不能提供這方面的建議。

3

Jeff的機制是創建某種緩存對象,ASP.Net會在某種間隔時自動重新創建 - 它似乎是一個ASP.Net特定的解決方案,因此可能無法幫助您(或我)很多在Java世界。

https://stackoverflow.fogbugz.com/default.asp?W13117

阿特伍德:嗯,我本來要求在Twitter上,因爲我想要的東西,重量輕。我真的不想寫一個Windows服務。我覺得那是帶外代碼。再加上實際上這項工作的代碼實際上是一個網頁,因爲對我而言,這是一個網站上的邏輯工作單位,就是一個網頁。所以,這就好像我們回到網站上,就像網站上的另一個請求一樣,所以我認爲它應該保持內聯,並且我們在Twitter上推薦給我們的那種小方法本質上是要在應用程序緩存中添加一些固定到期的應用程序,然後你有一個回調,所以當它過期時,它會調用一個特定的函數來完成這項工作,然後你將它添加到緩存中,並且過期時間相同。所以,這是一點點,也許「貧民窟」是正確的話。

我的做法一直是有操作系統(即cron或Windows任務調度程序)在某個區間在那個URL加載一個特定的URL,然後設置一個網頁,以檢查它的隊列,並執行任何任務是需要,但我很想聽聽有沒有更好的方法。

從成績單,它看起來像FogBugz也使用加載URL方法的Windows服務。

Spolsky:所以我們有這個特殊的頁面叫做heartbeat.asp。那頁,每當你打它,任何人都可以在任何時候打它:不傷。但是當頁面運行時,它會檢查一個等待任務隊列,看看是否有任何需要完成的任務。如果有任何需要完成的事情,它會做一件事,然後再次查看該隊列,如果還有其他事情要做,它會返回一個加號,並且它返回的整個網頁只是一個帶有加號的單個字符在裏面。如果沒有其他工作要做,隊列現在是空的,它返回一個減號。所以,任何人都可以調用它並多次點擊它,你可以在你的網頁瀏覽器中加載heartbeat.asp,你按Ctrl-R Ctrl-R Ctrl-R Ctrl-R直到你開始變得不重要。當你完成後,FogBugz將完成它需要完成的所有維護工作。所以這是第一部分,第二部分是一個非常非常簡單的Windows服務,它的全部工作是調用heartbeat.asp,如果它得到一個加號,很快再調用它,並且如果它得到一個減號調用它再次,但不是一段時間。所以基本上這個Windows服務總是在運行,它有一個非常非常非常簡單的任務,只需點擊一個URL,並查看它是否得到一個加號或一個減號,然後根據是否再次運行它有一個加號或一個減號。顯然你可以在這個主題上做任何你想要的變體,比如,例如,你實際上可以,而不是隻返回一個加號或減號,你可以說「好吧,在60秒內給我回電話」或者「我有更多的工作要做。「這就是它的工作原理...所以它只是運行維護服務,你知道,它就像是運行維護服務的代碼的半頁,它永遠不會改變,它沒有任何的邏輯,它只包含使得這些網頁以某種保證的頻率被調用的撓癢癢。在heartbeat.asp的網頁中,有一些代碼需要維護一個需要完成的任務隊列,並查看已經過了多少時間,並且您知道,深夜維護和每七天都會刪除所有舊的消息已被標記爲垃圾郵件和各種維護後臺任務。呃,那就是這樣。

5

如前所述,Quartz是一個標準的解決方案。如果您不關心跨重新啓動時的後臺任務的集羣或持久性,您可以使用內置的ThreadPool支持(Java 5,6)。如果您使用ScheduledExecutorService,則可以將Runnables放入後臺線程池,該池在執行之前會等待特定時間。

如果您關心集羣和/或持久性,您可以使用JMS隊列進行異步執行,儘管您仍然需要某種延遲後臺任務的方式(您可以使用Quartz或ScheduledExecutorService來執行此操作)。

2

我們使用jtcron作爲我們的預定後臺任務。 它運作良好,如果你瞭解cron,它應該對你有意義。