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、全部用異步方式;


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM