应该如何实现 DbContext 和与 DB 的连接来处理负载测试?

How DbContext and connections to DB should be implemented to handle load testing?

我最近开始实施一些负载测试。 我正在使用 .NetCore、EF Core 2.2 和 Postgres。

我正在调用我的测试服务器(HttpClient client.PostAsync("/api/resource");)。

我发现很少有请求因连接过多而失败 (The connection pool has been exhausted, either raise MaxPoolSize (currently 100) or Timeout (currently 15 seconds))。所以我实施了这样的方法:

services.AddDbContext<MyDbContext>(optionsAction: optionsBuilder =>
    optionsBuilder.UseNpgsql(Config.ConnectionString,
    optionsAction =>
    {
        optionsAction.EnableRetryOnFailure(5, TimeSpan.FromSeconds(10), null);
    }));

它有点帮助,但是,当调用例如500 个请求我收到错误。

我想,它应该以某种方式工作,例如如果系统能够同时处理 100 个请求(例如 100 个到数据库的连接),则剩余的请求(使用 MyDbContext)应该等待(而不是失败)。

所以我的问题是:

  1. 在高负载下,请求会因为最大可能的并发连接数而失败是否正常?
  2. 如果以上为真 - 通常的方法是使用 EnableRetryOnFailure?
  3. 是否可以让其他请求以非阻塞方式等待(例如最多 20 秒),直到有一些连接可用?
  4. 或者可能有其他配置选项(在 EF 核心或 MVC 中)使其他请求等待可用连接(来自连接池)而不是因异常而失败?

您的应用程序中存在一个错误,导致交易完成后 return 连接到池(所谓的“连接泄漏” ).

100 个连接对于连接池来说太大了(除非机器有 100 个内核和本地 SSD)。

这个想法是,当您想要执行数据库事务时,您从池中获取一个连接,完成您的工作,提交事务和 return 到池的连接。通常情况下,OLTP 事务在数据库中花费的时间很短,以这种方式您可以轻松处理数千个并发用户会话。

这一切都取决于您的交易很短的假设。如果不是,您可能会遇到并发问题,因为锁会一直保持到事务结束。此外,长事务会使 autovacuum 无法执行其救命工作。