c# - 为什么在增加用户时使用 IHttpClientFactory 会出现 .NET Core API 性能问题?

标签 c# performance asp.net-core .net-core aws-xray

我有一个 .NET Core WebAPI,我的 React UI 正在调用它来验证用户。它为此调用第 3 方 API。一切正常,但我们已经开始对其进行性能测试,并且当我们增加尝试同时登录的用户时,它的扩展性不佳。 (用时 30 秒)

我们调用的第 3 方 API 表示它们会在几毫秒内做出响应。

我的 API 托管在 AWS 上的 Kubertnetes 容器中。我已将 AWS X-ray 添加到代码中以尝试获取更多信息,但我不确定如何解释结果。

代码非常简单——这是 MyAuthenticationProvider 类的一个片段(构造函数采用一个指标收集器(用于 AWS X-Ray 和用于调用的 securityProvider http 客户端)

        metricCollector.StartCollection("Stage 1");
        HttpResponseMessage response = await securityProvider.SendAsync(requestMessage);
        metricCollector.EndCollection();

上述代码的 X 射线图像是:

enter image description here

X-Ray 是否显示该 API 确实等待 30 秒以上才能返回响应,我应该联系那家公司进行进一步调查,即使他们告诉我所有流量也在毫秒。

或者可能是我如何定义在 Startup.cs 的 MyAuthProvider 类中使用的 http 客户端,当并发用户增加时无法正确缩放?

这是 Startup.cs 中的代码

      services.AddTransient<IMyAuthenticationProvider>(ctx =>
        {
            IHttpClientFactory clientFactory = ctx.GetRequiredService<IHttpClientFactory>();
            return new MyAuthenticationProvider(
                clientFactory.CreateClient("3RDPARTYAUTHCLIENT"),
                ctx.GetService<IMetricCollector>());
        });

我要提高性能的另一件事是引入 Redis 来缓存其中一些响应,因为它们会多次调用不同的操作,但结果将是相同的

最佳答案

虽然您只创建了 1 个命名的 HttpClient,但您已将 IMyAuthenticationProvider 的服务生命周期设置为 transient

这意味着通过创建 IMyAuthenticationProvider 实例,您基本上失去了单个 HttpClient 的大部分好处 < strong>每次请求一个(在最好的情况下,这将与每个客户端请求同义,但不要与范围服务混淆)。

这会大大降低您的应用程序速度,并且可能是应用程序扩展性能不佳的原因。

您试图清楚地使用单个 HttpClient,它通常是 static 或包装为单例类中的非静态实例。并且仍然是a good solution for short-lived console applications等等,但是在这种情况下,我将允许 IHttpClientFactory 解析客户端。

ASP.NET Core 中 IHttpClientFactory 的主要目标是确保正确创建 HttpClient 实例(taking into account things like DNS changes,单个 HttpClient 实例不会处理)同时消除套接字耗尽。

通过 IHttpClientFactory 注入(inject)的 HttpClient 实例有一个 transient lifetime (文档是相互冲突的,并且出于某些荒谬的原因提到了 transient 2x 和 scoped 1x)所以我IMyAuthenticationProvider 的生命周期设置为 scoped 以允许尽可能多地重复使用.

有一个运行时间较长的单例 IHttpClientFactory,在这种情况下,不应使用注入(inject)的较短生命周期的 HttpClient

MSFT :

Do not resolve a scoped service from a singleton and be careful not to do so indirectly

虽然注入(inject)的 HttpClient 对象是 transient 的,但使用 IHttpClientFactory 可以池化 HttpMessageHandler 对象,这些对象可以并且将被多个 HttpClient 实例。

尝试:

services.AddHttpClient<IMyAuthenticationProvider, MyAuthenticationProvider>();
services.AddHttpClient<IMetricCollector, MetricCollector>();
...

services.AddScoped<IMyAuthenticationProvider, MyAuthenticationProvider>();
public class MyAuthenticationProvider : IMyAuthenticationProvider
{
  private readonly HttpClient _httpClient;

  public MyAuthenticationProvider(HttpClient httpClient)
  {
      _httpClient = httpClient;
  }

  ...
}

关于c# - 为什么在增加用户时使用 IHttpClientFactory 会出现 .NET Core API 性能问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69510364/

相关文章:

c# - 并发与正常收集?

c# - groupbox.Controls[i] 或 panel.Controls[i] 如何工作?

performance - CSV 生成速度极其缓慢

sql 查询连接多个表 - 太慢(8 个表)

c# - 将数据从 ModelBinder 传递到自定义 InputFormatter

css - ASP.NET Core 2.1 根据数据库中的数据在布局中插入 CSS

c# - visual studio xamarin.forms 中的秒表将 100 毫秒添加到 react 时间测试

c# - 如何在 SAPI 5.4 C# 程序中加载文本语法?

java - 如何提高 Oracle-DB 中 CLOB 和 LONG 值的查询性能(cx_Oracle 与 OJDBC)?

c# - EntityFramework 核心 2 - ValueGeneratedOnAddOrUpdate