应如何实现 DbContext 和与数据库的连接来处理负载测试?

Joh*_*Bzz 1 c# postgresql ef-core-2.2

我最近开始实施一些负载测试。我正在使用 .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);
    }));
Run Code Online (Sandbox Code Playgroud)

它有点帮助,但仍然,当调用例如 500 个请求时,我遇到了错误。

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

所以我的问题是:

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

Lau*_*lbe 5

您的应用程序中存在一个错误,导致事务完成后不会将连接返回到池中(所谓的“连接泄漏”)。

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

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

这一切都取决于您的交易时间很短的假设。如果不是,您可能会遇到并发问题,因为锁会一直保持到事务结束为止。此外,长事务可能会阻止 autovacuum 发挥其救生作用。