你們都知道,使用HttpClient,在併發量不大的狀況,通常沒有任何問題;可是在併發量一上去,若是使用不當,會形成很嚴重的堵塞的狀況。json
解決方案以下:api
1、能夠參考微軟官方提供的方法:https://docs.microsoft.com/zh-cn/aspnet/core/fundamentals/http-requests?view=aspnetcore-2.2併發
2、個人解決方案是根據官方提供的方法,選擇一種最適合項目的寫法進行改造。app
一、nuget添加包Microsoft.AspNetCore.Http;異步
二、startup裏ConfigureServices方法添加代碼:async
//添加httpclient方法 services.AddHttpClient("ApiServiceName", c => { c.BaseAddress = new Uri(Configuration["ApiConfig:SystemService"]);//地址從配置文件appsettings.json裏取 c.Timeout = TimeSpan.FromSeconds(30);//超時間時間設置爲30秒 });
三、在須要用的地方注入進去:(通常在構造函數裏)函數
private ILogger logHelper; private readonly IHttpContextAccessor httpContextAccessor; private readonly IHttpClientFactory _clientFactory; HttpClient client; public articleService(ILogger<reportService> logger, IHttpContextAccessor _httpContextAccessor, IHttpClientFactory clientFactory) { logHelper = logger; httpContextAccessor = _httpContextAccessor; _clientFactory = clientFactory; client = _clientFactory.CreateClient("ApiServiceName"); }
client = _clientFactory.CreateClient("SystemService"); 這句話也能夠在具體的方法裏執行,由於咱們的項目所有都是調用接口,因此放構造函數比較省事。post
四、添加一個公共方法:ui
using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Logging; using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Net.Http; using System.Text; using System.Threading.Tasks; namespace MuXue.Common { /// <summary> /// 異步調用,而且client是注入方式,傳過來 /// 2019-8-21 /// 李樸 /// </summary> public class MyHttpClientHelper { public async Task<T> GetData<T>(HttpClient client, GateWay action, dynamic param) { string paramStr = JsonConvert.SerializeObject(param); string jrclientguid = Guid.NewGuid().ToString("n"); try { LogHelper.Info($"MyHttpClientHelper開始,url={client.BaseAddress},action={Utils.GetEnumDescription(action)},postData={paramStr} ,jrclientguid={jrclientguid}---------"); client.DefaultRequestHeaders.Add(CommonConstant.jrclientguid, jrclientguid); HttpResponseMessage response; using (HttpContent httpContent = new StringContent(paramStr, Encoding.UTF8)) { httpContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json"); response = await client.PostAsync("api/" + Utils.GetEnumDescription(action), httpContent); } if (response != null && response.IsSuccessStatusCode) { T resp = await response.Content.ReadAsAsync<T>(); return resp; } else { return default(T); } } catch (Exception ex) { throw; } finally { LogHelper.Info($"MyHttpClientHelper結束,url={client.BaseAddress},action={Utils.GetEnumDescription(action)},postData={paramStr} ,jrclientguid={jrclientguid}---------"); } } } }
這裏的參數 GateWay action 也能夠換作是接口地址(不包含域名);
五、接着在第3步的那個類裏,須要調用接口的地方寫方法:
//二、取接口裏取 MyHttpClientHelper myHttpClientHelper = new MyHttpClientHelper(); Result<List<Article>> resp=await myHttpClientHelper.GetData<Result<List<Article>>>(client, GateWay.GetNoticeList, null);
這樣就完成了。url
六、所有用異步方式;