WebApi系列~HttpClient的性(xing)能隱患
最(zui)近在進行(xing)開發(fa)過(guo)(guo)程中,基于(yu)都是(shi)(shi)接(jie)口開發(fa),A站接(jie)口訪問B接(jie)口接(jie)口來請(qing)求數據,而在這(zhe)個過(guo)(guo)程中我們(men)使用(yong)的(de)(de)(de)(de)是(shi)(shi)HttpClient這(zhe)個框(kuang)架,當然也(ye)是(shi)(shi)微軟自己的(de)(de)(de)(de)框(kuang)架,性(xing)能(neng)當前(qian)沒有(you)問題,但如果你直接(jie)使用(yong)官(guan)方(fang)的(de)(de)(de)(de)寫法,在高并發(fa)時(shi)候,會(hui)有(you)很(hen)大(da)的(de)(de)(de)(de)性(xing)能(neng)隱患,因為它官(guan)方(fang)使用(yong)的(de)(de)(de)(de)是(shi)(shi)using的(de)(de)(de)(de)方(fang)式(shi),而對于(yu)請(qing)求量(liang)比較大(da)時(shi),這(zhe)種方(fang)法對TCP建立也(ye)會(hui)過(guo)(guo)高,即使用(yong)完馬上釋(shi)放也(ye)會(hui)有(you)很(hen)多time_out的(de)(de)(de)(de)請(qing)求,所有(you)決定(ding)把某個用(yong)到httpclient的(de)(de)(de)(de)組件做成靜態化的(de)(de)(de)(de)!
明細

統計

調用,中(zhong)規中(zhong)矩的寫(xie)法
using (var http = new HttpClient()) { var json = JsonConvert.SerializeObject(new { target_index = projectName, timestamp = DateTime.Now.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ss.fffZ"), Level = level.ToString(), Message = message }); json = json.Replace("target_index", "@target_index").Replace("timestamp", "@timestamp"); var httpContent = new StringContent(json, Encoding.UTF8); httpContent.Headers.ContentType = new MediaTypeHeaderValue("application/json"); var result = http.PostAsync(apiLoggerUri, httpContent).Result; }
優化它,做(zuo)成TCP長(chang)鏈接,所(suo)以請(qing)求走一(yi)個通道
private static readonly HttpClient _httpClient; private ApiLoggerOptions _config; static ApiLogger() { _httpClient = new HttpClient(); _httpClient.Timeout = new TimeSpan(0, 0, 10); _httpClient.DefaultRequestHeaders.Connection.Add("keep-alive"); }
keep-alive關鍵字可以(yi)(yi)理解為(wei)一個長鏈(lian)接,超時(shi)時(shi)間也可以(yi)(yi)在上(shang)面進行設置,例如10秒(miao)的超時(shi)時(shi)間,當然并發量太(tai)大,這個10秒(miao)應該會拋棄很多請求
發送請求的代碼沒有了using,即這個httpclient不會被手動dispose,而是(shi)由系(xi)統控制它,當然你(ni)的程(cheng)序重啟時,這也就被回收了。
var json = JsonConvert.SerializeObject(new { target_index = projectName, timestamp = DateTime.Now.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ss.fffZ"), Level = level.ToString(), Message = message }); json = json.Replace("target_index", "@target_index").Replace("timestamp", "@timestamp"); var httpContent = new StringContent(json, Encoding.UTF8); httpContent.Headers.ContentType = new MediaTypeHeaderValue("application/json"); _httpClient.PostAsync(apiLoggerUri, httpContent).Wait();
通(tong)過上(shang)面的(de)改(gai)造(zao),我們我系統性能(neng)得到了改(gai)善,TCP的(de)連接數也降(jiang)下(xia)來了

所以對于長鏈接的多(duo)路復用技術,相對于請求過多(duo)的情況還是(shi)最(zui)省(sheng)資源的!