2011-05-09 43 views
5

我們在我們的應用程序中有一個大的進程,每個月運行一次。此過程通常在大約30分鐘內運行,並生成342000個左右的日誌事件。最近我們使用WCF將日誌記錄更新爲集中式模型,現在在性能上遇到了困難。而以前的解決方案將在大約30分鐘內完成,新的日誌記錄現在需要3或4個小時。這似乎是因爲應用程序實際上在等待WCF請求完成,然後繼續執行。 WCF方法已經被配置爲IsOneWay,並且我將客戶端的調用包裝到了另一個線程中的WCF方法,以嘗試防止這種類型的問題,但它似乎沒有奏效。我曾考慮過使用異步WCF調用,但是在嘗試其他方法之前我想問一下,我會問在這裏看看是否有更好的方法來處理這個問題。通過WCF進行記錄而不會讓東西變慢

+1

無法給出真實的答案,但是:您正在尋找消息隊列。有Microsoft Message Queue作爲Windows的一部分,或者有NServiceBus,可能還有其他的。 Message Queue允許您的應用程序將這些文件發送到本地服務中(這樣您的應用程序就不會陷入停滯狀態),Queue會處理髮送消息,錯誤處理/重試以及所有這些內容。或者,批量WCF呼叫。不要撥打每條消息的電話號碼,而是撥打100號電話並一次發送。 – 2011-05-09 21:36:51

回答

4

342000個日誌事件,如果我正確地做了我的數學,出來每秒190個日誌事件。我認爲你的問題可能與WCF中的默認限制設置有關。即使您的方法設置爲單向,取決於您是否爲每個記錄的事件創建新的代理,在創建代理時,調用該方法仍將阻止,通道已打開,如果您正在使用基於HTTP的綁定,它將阻塞,直到服務接收到消息(當接收到消息時,基於HTTP的綁定發回一個單向方法調用的響應)。默認的WCF限制在服務端將併發實例限制爲10個,這意味着一次只能處理10個請求,並且任何進一步的請求都會排隊,因此需要使用HTTP綁定進行配對,並且前10個請求之後的任何請求都是將阻止客戶端,直到它成爲處理的10個請求中的一個。不知道你的服務是如何配置(例如模式等),很難說還不止這些,但是如果你使用每次呼叫實例化,我建議設置你的ServiceBehaviorMaxConcurrentCallsMaxConcurrentInstances的東西要高得多(在默認值分別是16和10)。

此外,建立在提到關於聚合多個事件,並提交他們一下子什麼人,我發現它有助於建立一個靜態Logger.LogEvent(eventData)方法。這樣在整個代碼中使用起來很簡單,並且您可以控制您的日誌在整個應用程序中的行爲方式,例如配置一次應該提交多少事件。

+0

感謝您的回覆。最初我專注於「發送並忘記它」。將它轉儲到服務器,讓它處理掉落。如果我在服務器上丟棄消息或日誌堵塞,我將分別解決該問題。我現在困惑的是爲什麼當我在一個單獨的線程中將消息發送到服務器時,它會影響我的主線程?我明白你的觀點是爲了提高效率,並且我可能最終會這樣做,但純粹在學術上,爲什麼不是這個單獨的線程使我無法擺脫這種緩慢? – omatase 2011-05-09 22:55:58

+0

如果不知道如何實現單獨的線程,這很難回答。但是,如果它與節流有關,並且WCF調用比大多數其他操作花費的成本要高得多,那麼可能有意義的是,如果仍然只有10個節點,程序可能還需要很長時間才能完成請求正在處理中。有沒有一種方法可以判斷一切是否已經完成,並且您的程序正在趕上日誌記錄請求?您是從操作完成還是記錄時間開始的時間戳? – 2011-05-09 23:38:04

0

總是有傳統syslog有很多在Windows上運行的系統日誌守護進程。它被設計成比WCF更有效的集中式日誌記錄方式,WCF是專爲較少的密集操作而設計的,特別是如果你不使用tcpip WCF配置。

換句話說,有一個去與這 - 工作的正確工具。

3

撥打電話到另一個進程或遠程服務(即調用WCF服務)是你可以在應用程序做的最昂貴的東西。做342,000次只是純粹的瘋狂!

如果你必須登錄到集中式的服務,你需要積累日誌條目的批生產,然後,只有當你有說1000左右的內存,它們全部發送到服務於一體的打擊。這會給你一個合理的性能改進。在30分鐘內

1

log4net具有存在的調用線程的上下文之外的緩衝系統,因此,儘管它記錄也不會耽誤你的電話。其用法應該從許多appender config examples中清楚 - 搜索術語bufferSize。它用於許多較慢的appender(例如遠程處理,電子郵件),以保持源代碼線程無需等待較慢的日誌記錄而移動,並且還有一個通用緩衝meta-appender,可用於任何其他附加目的地。

我們將它與AdoNetAppender一起使用在一個體積相似的系統中,它的工作原理非常奇妙。