【发布时间】:2022-12-09 23:23:44
【问题描述】:
我们在 ECS 中托管了一个 .net API,它使用 Entity Framework 从无服务器 v1 集群查询数据。在正常负载下,此服务执行得非常好,但当流量激增需要 RDS 集群扩展到更多 ACU 时,我们会在 API 中看到很多连接错误。
An error occurred using the connection to database '\"ourdatabasename\"' on server '\"tcp://ourcluster.region.rds.amazonaws.com:5432\"'.
基础架构的高级概述如下所示:
CloudFront >> Load Balancer >> ECS Fargate >> RDS Aurora PostgeSQL Serverless v1
堆栈信息:
- .Net 6 API 为 Linux 编译
- 实体框架核心 6.x
- Npgsql.EntityFrameworkCore.PostgreSQL 6.x
- PostgreSQL 10.18
在过去的一年里,我们确实公开了关于这个问题的 AWS 支持案例,但这些案例基本上总是得出这样的答案,即这是一个实施问题,而不是基础设施问题。
我们可以通过在我们的 API 上运行 k6 压力测试(当然绕过 CloudFront 缓存层)来轻松重现该问题,以生成足以触发 RDS 集群扩展的峰值。
在过去的一年里,我们通过以基本上不需要扩展的容量配置 RDS 来解决这个问题。这当然是在浪费钱,而不是无服务器的目的,所以我们想找到根本原因并解决这个问题。
我们已经尝试过的一些事情:
- 我们已经尝试了无服务器 v2它应该以完全不同的方式扩展,因为它只是同一个 vm 从托管机器消耗更多资源。但我们的初步结论是,情况更糟。我们还不明白为什么会这样,但它似乎触发了相同的效果,但比 v2 扩展得更快/更多。使用 v1,我们每秒遇到大约 400 个请求的麻烦,而使用 v2,它是 150rps。
-
EnableRetryOnFailure似乎有点帮助,但不是很多。我们暂时将其保留为 Npgsql 实现的默认配置。 - 我们对
Maximum Pool Size连接字符串参数进行了试验。在 300 时它似乎好一点,但它并没有解决问题。 - 更改 ECS/ALB 的缩放行为,甚至只是预先缩放以处理峰值负载都没有改变任何东西。
我们没有尝试过:
- RDS Proxy,它应该可以解决您所有的连接池问题。但我们不确定这是否是一个池化问题。我们不热衷于信任另一个黑盒服务来解决我们的第一个黑盒服务 (aurora serverless) 存在的问题。而且它并不便宜。如果所有 SO 现在都让我们相信这是圣杯,那么我们肯定会尝试一下。
- RDS 的数据 API,如果您没有正确设置,就不会出现连接管理问题吗?将所有 EF 代码重写为数据 API 请求是一项巨大的投资,如果它仍然没有用于无服务器 v2,我不确定它对服务的看法。所以,我认为暂时不是。
这个问题的第一个目的是试图找到可以帮助我们理解正在发生的事情的人。帮助我们了解错误及其来源。我们知道您不能指望 ECS+RDS 可以神奇地处理您施加给它的所有负载。但是,如果我们不完全理解它是如何崩溃的,我们就无法想出如何创建潜在的故障转移机制或如何使系统更优雅地失败。
如果有人知道神奇的设置但不知道为什么那当然也很好 :) 然后我们也许可以自己弄清楚为什么并与社区分享 ;)
如有需要,请随时提出更多问题。
【问题讨论】:
标签: postgresql entity-framework-core amazon-ecs connection-pooling aws-aurora-serverless