希望用多執行緒的非同步方式在同一時間大量送出HttpRequest,
再以HttpGet的呼叫特定的Web API 取得回傳結果。

但總是在特定的連線數之後就發生Timeout,
一開始我們測試時只連一台,所以沒有發生Timeout,
當連線主機及連線數增加到特定數量後,開始發生Timeout。


【解決】

1. 先確認每次連線完「是否有關閉連線」
using(WebResponse wr = webRequest.GetResponse()) {
         // 做你要做的事
}


2. 設定Timeout和KeepAlive參數
webRequest.Timeout = 60000;
webRequest.KeepAlive = false;


設定KeepAlive 避免建立與網際網路資源的持續連線
不過我在設定之後,Timeout時間是延後了,但仍然是會發生Timeout。


3. 檢查是否有可能是連線數的限制
查了相關文章,是「 ASP.NET 託管應用程式的預設連接限制為10,而所有其他則為2
沒手動設定,IIS同一時間的限制是10條,
10條滿之後如果沒有釋放連線就會Timeout,
因此送出連線前手動設定連線數,
同時也參考了一些建議,設定了相關的參數

// 調整連線數量
ServicePointManager.Expect100Continue = false;
ServicePointManager.UseNagleAlgorithm = false;
ServicePointManager.DefaultConnectionLimit = 1200;

雖然把連線數已經開到很大,幾次的反複測試之後,還是有發生少數幾條連線的Timeout,

雖比起之前發生的時間雖然延後很多,
Timeout數變少,但仍然特定頻率就發生Timeout,
猜想應該是連線還沒有釋放之前又滿了,
其實沒真正的釋放連線資源。

查了文章,有人建議做「Garbage Collector 」
雖然很多人並不建議這樣做,但如果還是發生,
或許建議可以試試,強制回收連線資源。


GCSettings.LargeObjectHeapCompactionMode = GCLargeObjectHeapCompactionMode.CompactOnce;
GC.Collect();

 

【心得】有些人在每次連線完畢後做GC,
我怕這樣反而造成系統底層的更大負擔。

在測試的過程中發現,
當重啟IIS或是暫時先中止測試一段較長的時間再執行,
這幾次的執行過程並沒有發生Timeout,
我猜想有可能是因為連線被系統給釋放掉就正常了。

連續的測過程中,
即使每一條連線看似已斷線,或許實際上有些仍被暫存

再連線時就很容易造成連線數又滿了,
因此在每一次準備開始開始執行程式之前就先執行GC來釋放所有連線資源

當完成以上的這些設定後,就正常了。

arrow
arrow
    創作者介紹
    創作者 湯瑪的吳 的頭像
    湯瑪的吳

    安達利機車行

    湯瑪的吳 發表在 痞客邦 留言(0) 人氣()