System.IO.FileSystemWatcher 監控網路伺服器文件夾 - 性能注意事項
我想查看網路伺服器上的文件夾樹是否有更改。這些文件都有一個特定的副檔名。樹中有大約 200 個文件夾和大約 1200 個文件,副檔名為我正在查看。
我無法編寫要在伺服器上執行的服務(禁止!),因此解決方案必須在客戶端本地。及時性並不是特別重要。我可以忍受一分鐘或更長時間的通知延遲。我正在關注創建、刪除、重命名和更改。
使用 .NET System.IO.fileSystemWatcher 會在伺服器上產生大量負載嗎?
10 個單獨的觀察者如何減少被觀察的文件夾/文件的數量?(從 700 個文件夾減少到 200 個,總共從 5500 個文件減少到 1200 個)更多網路流量而不是更少?我的想法是在伺服器上重新洗牌,將監視的文件放在一棵樹下。我可能並不總是有這個選項,因此有觀察者團隊。
我想另一種解決方案是定期檢查 FSW 是否在伺服器上創建了過度負載,或者它是否由於一大堆 SysAdmin 類型的原因而不起作用。
有一個更好的方法嗎?
從伺服器負載的角度來看,在您描述的場景中使用IO.FileSystemWatcher進行遠端更改通知可能是最有效的方法。它在內部使用FindFirstChangeNotification和ReadDirectoryChangesW Win32 API 函式,這反過來又以優化的方式與網路重定向器通信(假設標準 Windows 網路:如果使用第三方重定向器,並且它不支持所需的功能,事情會成功根本不工作)。.NET 包裝器還使用非同步 I/O 和一切,進一步確保最大效率。
這個解決方案的唯一問題是它不是很可靠。除了必須處理暫時斷開的網路連接(這不是什麼大問題,因為在這種情況下 IO.FileSystemWatcher 會觸發一個您可以處理的錯誤事件),底層機制具有某些基本限制。來自 Win32 API 函式的 MSDN 文件:
- 當緩衝區長度大於 64 KB 並且應用程序正在通過網路監視目錄時,ReadDirectoryChangesW失敗並顯示 ERROR_INVALID_PARAMETER。這是由於底層文件共享協議的數據包大小限制
- 為遠端文件系統呼叫FindFirstChangeNotification時可能不會返回通知
換句話說:在高負載下(當您需要一個大緩衝區時),或者更糟糕的是,在隨機未指定的情況下,您可能不會收到您期望的通知。這甚至是本地文件系統觀察者的問題,但更多的是網路上的問題。這里關於 SO 的另一個問題更詳細地詳細說明了 API 的固有可靠性問題。
使用文件系統觀察程序時,您的應用程序應該能夠處理這些限制。例如:
- 如果您要查找的文件有序列號,請儲存您收到通知的最後一個序列號,以便您可以在未來的通知中查找“空白”並處理您未收到通知的文件;
- 收到通知後,請始終進行完整目錄掃描。這聽起來可能很糟糕,但由於掃描是事件驅動的,它仍然比啞輪詢更有效。此外,只要您將文件總數保持在單個目錄中,以及要掃描的目錄數量在 1000 左右,此操作對性能的影響無論如何應該是非常小的。
設置多個監聽器是你應該盡可能避免的事情:如果有的話,這會讓事情變得更不可靠……
無論如何,如果您絕對必須使用文件系統觀察程序,只要您了解這些限制,事情就可以正常工作,並且不要期望每個修改/創建的文件都有 1:1 通知。
因此,如果您有其他選擇(基本上,讓寫入文件的過程以基於非文件系統的方式通知您:任何正常 RPC 方法都將是一種改進……),從可靠性的角度來看,這些絕對值得研究看法。