asp.netcore 高并发下使用HttpClient的方法
大家都知道,使用HttpClient,在并发量不大的情况,一般没有任何问题;但是在并发量一上去,如果使用不当,会造成很严重的堵塞的情况。
解决方案如下:
一、可以参考微软官方提供的方法:https://docs.microsoft.com/zh-cn/aspnet/core/fundamentals/http-requests?view=aspnetcore-2.2
二、我的解决方案是根据官方提供的方法,选择一种最适合项目的写法进行改造。
1、nuget添加包Microsoft.AspNetCore.Http;
2、startup里ConfigureServices方法添加代码:
//添加httpclient方法 services.AddHttpClient("ApiServiceName", c => { c.BaseAddress = new Uri(Configuration["ApiConfig:SystemService"]);//地址从配置文件appsettings.json里取 c.Timeout = TimeSpan.FromSeconds(30);//超时间时间设置为30秒 });
3、在需要用的地方注入进去:(一般在构造函数里)
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"); 这句话也可以在具体的方法里执行,因为我们的项目全部都是调用接口,所以放构造函数比较省事。
4、添加一个公共方法:
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 也可以换做是接口地址(不包含域名);
5、接着在第3步的那个类里,需要调用接口的地方写方法:
//2、取接口里取 MyHttpClientHelper myHttpClientHelper = new MyHttpClientHelper(); Result<List<Article>> resp=await myHttpClientHelper.GetData<Result<List<Article>>>(client, GateWay.GetNoticeList, null);
这样就完成了。
6、全部用异步方式;
作者:沐雪
文章均系作者原创或翻译,如有错误不妥之处,欢迎各位批评指正。本文版权归作者和博客园共有,如需转载恳请注明。
如果您觉得阅读这篇博客让你有所收获,请点击右下方【推荐】
为之网-热爱软件编程 http://www.weizhi.cc/