HttpClient所引爆的Sockets Port耗盡問題
最近在跨單位合作某通訊軟體API時再度觸及到這個議題,擔心某同事會寫出爆掉的程式碼,因此寫了此篇文章真實的驗證以利日後查閱。
HttpClient不慎引發Sockets資源耗盡
從2015-2016年之間我在文章中一直呼籲,如果你不確定你的HttpClient將要怎麼的被使用,那就最好不要用!不要以為用using Statement就可以安全下樁,這反而是引爆你的Socket 65535個連接埠耗盡的關鍵點。原因就是因為IDisposable在實作關閉時,依照TCP協定的規定必須實作等候MSL(Maximum Segment Lifetime)時間延遲,以確保另一通訊端關閉連接,以至於形成TIME-WAIT,這就是爆掉的原因。
驗證程式碼如下,隨便開個ASPX把方法丟進去就知道效果。
protected void uBtn_Click(object sender, EventArgs e)
{
uMsg.Text = "";
for (int i = 0; i < 10; i++)
{ //這裡很自以為是地用了using嘍!
using (var oHC = new System.Net.Http.HttpClient())
{
var oResult = oHC.GetAsync("https://api.myjson.com/bins/nx06k").GetAwaiter().GetResult();
uMsg.Text += oResult.Content.ReadAsStringAsync().Result;
}
}
}
結果很簡單,用netstat看就知道效果,不多不少共10個TIME-WAIT,想想看當你的程式碼被執行一萬次會怎樣?
雖然微軟建議往HttpClient遷移,但是如果你懶得另行設計Singleton或Lazy(T)的話,我建議還是留在最完整與強大的HttpWebRequest尤佳。
相關參考:
- 延伸參考:YOU'RE USING HTTPCLIENT WRONG AND IT IS DESTABILIZING YOUR SOFTWARE;HttpClient因IDisposable反而引發連線資源耗盡(TIME_WAIT)問題
- Singleton Design Pattern
- UWP及.NET Framework 4 Client Profile適用的HttpClient()