2011-05-25 23 views
2

在我們的網站上,我們的版主可能會審閱用戶發佈的內容。這也適用於視頻,但視頻需要先轉換。這可以在夜間自動發生(通過Windows服務),也可以在主持人手動啓動時立即發生。在服務器上運行多個操作

現在,這最後一部分是我的問題來自何處。起初我以爲我只是寫一個單獨的服務來處理轉換。無論何時主持人開始轉換,數據庫中的記錄都會更新以將其標記爲單次轉換。然後服務將處理剩下的事情。當它只是一個文件時,這一切都很好。

但想象一下這種情況,主持人#1啓動服務。該服務運行並啓動文件轉換。在該過程中,主持人#2開始轉換不同的文件。它會嘗試啓動服務,但因爲它已經啓動而失敗。該文件將被標記爲單獨轉換,但不會轉換,因爲它無法啓動服務。

現在我正在尋找新的想法來解決這個問題。

  1. 是否可以運行一個服務的多個實例?
  2. 我可以使服務更具動態性嗎?例如,如果版主#2開始轉換,它將啓動服務,但是如果服務已經啓動,是否可以將文件添加到列表中? (在服務開始時,我創建一個列表,從數據庫中讀取每個文件,尋找單個轉換標誌)
  3. 我知道我一直在想服務,是否有另一種方式來處理服務器上的操作可以處理版主的多個請求?

我意識到它可能聽起來有點模糊,所以如果你有任何問題請問。也許我應該提供一些額外的信息,目前我是一名在實習中工作的學生,我的發起人並不真的想要一個文件幾乎立即轉換。他們希望在晚上進行轉換,除非主持人手動爲單個文件啓動轉換。此外,網站和文件系統位於同一臺服務器上(數據庫位於單獨的服務器上)。基本上,這些工作將在網站運行的同一臺服務器上完成(它目前不能分開)。他們擔心服務器的性能。

如有任何意見,將不勝感激! 各種問候, 弗洛里斯

+0

我會感到驚訝,如果asp.net不具備某種支持工作隊列。你創建一個固定數量的工作線程(可能是1個),完成一個工作單元,然後繼續檢查新工作,直到出現問題。 – bwawok 2011-05-25 17:16:13

+0

我不是100%確定您的特定要求,但您是否考慮過多線程和線程池? – 2011-05-25 17:22:19

+2

如果服務始終在運行,並且只查看由請求時間戳(簡單隊列)排序的表,該怎麼辦?因此,它會定期查詢這個隊列表並按順序處理這些項目 - 它甚至可以將這些工作發送給多個線程。我錯過了什麼嗎? – 2011-05-25 17:22:40

回答

2

國際海事組織的理智的方式來處理這是任何形式的隊列。一個簡單的數據庫表(或一個redis列表)就足夠了。你的服務應該簡單地檢查:有工作要做嗎?我會這樣做:做,否則睡一會兒,然後重新查詢。作爲一個可選的額外的東西,像pub/sub這樣的東西可以用於更快的喚醒,所以在入隊和出隊之間沒有可察覺的延遲 - 但理想情況下,隊列/輪詢循環應該沒有額外的工作。

然後,批處理過程很簡單:將工作添加到隊列中。或者,您可能會優先考慮,以便主持人(或其他「現場」用戶)在進行後臺處理之前獲得工作。

可能多次運行同一個exe作爲服務(給它不同的服務名稱),但每個都需要顯式設置。說實話,在你的情況下它是不值得的:一個更簡單的選擇是讓多個工作線程服務隊列,這可以在一個進程中完成。

+0

所以基本上我只是用一個時間戳(當它被請求時)更新數據表並讓一個服務運行並檢查數據表是否在定時間隔。換句話說,服務一直在「運行」,但在沒有工作時會睡覺。如果服務一直運行,服務器性能是否會大幅降低? – 2011-05-25 17:52:20

+0

@弗洛里斯根本沒有。下一次您進入任務管理器時,啓用「由所有用戶顯示任務」並查看有多少事情默默無聞。只要確保你使用被動等待(即任意Thread.Sleep,一個計時器或等待處理),而不是主動等待('while(DateTime.Now 2011-05-25 18:33:46

+0

如果你確實去了有一個隊列,我會建議使用一個持久隊列。無論是您創建的數據庫管理隊列,還是使用MSMQ(內置於Windows)或[Rhino Queues](http://ayende.com/blog/3480/rhino-queues)等現有的隊列。 – hemp 2011-05-25 20:29:41

0

我會刪除主持人手動啓動服務的選項(只是我的首選項),並啓動一個線程輪詢您的數據庫以查找需要轉換的文件。

如果你有服務中的代碼,你可以在下面的函數中運行它。如果不是,則將該函數保留在單個線程下方,然後以編程方式在該函數內啓動該服務以執行轉換。這個問題的答案可以根據您是否擁有服務代碼並可以進行更改而發生重大變化。如果您可以修改它,您可以將相同類型的邏輯放入服務中。

在你的Global.asax.cs的Application_Start事件,我將開始一個新的線程不斷循環並檢查你的數據庫

using System.Threading; 


    void Application_Start(object sender, EventArgs e)   
    { 
     Thread VideoConversionThread = new System.Threading.Thread(new ThreadStart(VideoConversion)); 
     VideoConversionThread.Name = "VideoConversion"; 
     VideoConversionThread.IsBackground = true; 
     VideoConversionThread.Start(); 
    } 
    private void VideoConversion() 
    { 
     while (true) 
     { 
      //Get Count of records that need conversion. 
      if(Count > 0) 
      { 
       var records = //GetRecords from database that require conversion 
       foreach(var record in records) 
       { 
        //either spawn a seperate worker thread for each record or perform tasks here 

        //perform conversion 
        //update database to mark item as completed 
        // or 
        //in this single thread, you could also start the service 
        //(does the service Stop when it's finished?) 
        //(if so, you can monitor and wait for it to be stopped for each record) 
       } 
      } 
      Thread.Sleep(5000); //sleep 
     } 
     } 
+0

你的意思是刪除手動啓動版主轉換的選項嗎?如果是這樣,你的意思是每個視頻在當天上傳一段時間後都會更新。 如果每個視頻在上傳一段時間後都會更新,它可能會耗盡服務器的性能。或者我在這裏弄錯了嗎? 如果我仍然保留主持人手動啓動轉換的選項(但讓他們用請求更新數據庫並讓它檢查您的方法),您的情況可能會有效。 – 2011-05-25 18:03:06

+0

嗯,這個想法是,這個過程不斷地轉換文件,消除手動轉換請求的需要。我明白你說的是什麼。如果您只是希望能夠處理多個手動請求,則可以使用相同類型的邏輯,您只需要擁有一個表來跟蹤手動請求轉換的文件。然後,該過程應循環並運行每個文件。 – Jemes 2011-05-25 18:53:58

+0

事實上,相同的邏輯將起作用。這將是一個說服我的推銷員這樣做的問題。只要它不會在代碼未運行(睡眠)時耗盡網站性能。 – 2011-05-25 20:39:47

相關問題