从web服务器API并行调用时,快速增加AWS RDS上睡眠的MySQL连接数

从web服务器API并行调用时,快速增加AWS RDS上睡眠的MySQL连接数,mysql,entity-framework-core,amazon-rds,aspnetboilerplate,pomelo-entityframeworkcore-mysql,Mysql,Entity Framework Core,Amazon Rds,Aspnetboilerplate,Pomelo Entityframeworkcore Mysql,我使用的是aspnetboilerplate核心和entityframework核心 我有1个大的请求实体框架核心: var user = _userRepository.GetAll() .Include(u => u.FavoriteMeals).ThenInclude(c => c.Category) .Include(u => u.FavoriteRestaurants).ThenInclude(c => c.Cat

我使用的是aspnetboilerplate核心和entityframework核心

我有1个大的请求实体框架核心:

var user = _userRepository.GetAll()
            .Include(u => u.FavoriteMeals).ThenInclude(c => c.Category)
            .Include(u => u.FavoriteRestaurants).ThenInclude(c => c.CategoryMaster)
            .Include(u => u.FavoriteSpecialityMeals).ThenInclude(c => c.Speciality)
            .Include(u => u.FavoriteSuperBookings).ThenInclude(c => c.Boooking)
            .Include(u => u.FavouritePlaces).ThenInclude(c => c.Place)
            .Include(u => u.Followers).ThenInclude(u => u.User1)
            .Include(u => u.Followings).ThenInclude(u => u.User2)
            .FirstOrDefault(r => r.Id == id);
我使用AWS RDS MySQL。当我通过swagger调用API时,我可以看到到数据库的连接数增加到了58

那么我想知道:

有大约60个到数据库的连接是正常的吗?然后我计划使用这个api连接到一个移动应用程序

aws上的最大连接数限制为每部手机或全球。我的意思是,如果两个手机连接到我的api并调用相同的api函数,它们是否会因为达到最大连接数而被阻止

我如何优化它

谢谢

/////编辑

我发现我有很多请求保存在slepp状态

我怎样才能解决这个问题?我的代码如下所示:

builder.UseMySql(connectionString);
        //todo
        builder.EnableSensitiveDataLogging(true);
        builder.EnableDetailedErrors(true);
请在下面查找我的请求结果,以查找睡眠状态


许多连接以睡眠状态打开的原因是,默认情况下,Pomelo使用的连接池已启用(
pooling=true
),每个连接字符串最多100个连接(
MaxPoolSize=100
)。有关所有默认设置,请参见

因此,当60个人并行使用应用程序API时,或者例如,当使用3个不同的连接字符串时,每个字符串并行使用20个用户时,打开大约60个连接很容易

一旦这些连接被打开,默认情况下它们将有效地保持打开状态很长一段时间

默认设置为
ConnectionLifeTime=0
,MySqlConnector的连接池管理永远不会显式关闭它们。但是,在MySQL系统变量指定的秒数之后,它们将始终关闭。但是,由于默认情况下该变量设置为
28800
,MySQL需要8小时才能关闭曾经创建的池连接(与它们处于睡眠状态的时间无关)

因此,要减少并行连接的数量,可以禁用
(如果服务器不是本地托管的,则会产生一些性能影响的根本方法),或者通过
MaxPoolSize
ConnectionLifeTime
连接字符串参数来管理它们的生存期


在您提供的屏幕截图中,您可以看到主机的地址和端口有所不同,但这些是连接客户端的地址和传出端口

然而,我上面写的也适用于这里。因此,如果您从多个web服务器(从MySQL的角度来看,客户端)连接到数据库服务器,默认情况下,每个web服务器将管理自己的连接池,并保持多达100个连接处于打开状态

例如,如果您有一个负载平衡器设置,并且在它后面有多个web服务器,每个服务器都可以执行数据库查询,或者您使用一些无服务器技术(如AWS Lambda)运行API,其中您的API可能托管在多个不同的web服务器上,那么最终可能会有多个连接池(每个web服务器上的每个连接字符串一个)


我的问题是,这只适用于一个已连接的用户。我在我的应用程序中使用
Task.WhenAll()
,它并行启动多个api请求,我还在api中使用异步方法创建一些新线程

如果您的客户端向托管在多个web服务器/AWS Lambda上的API发送多个web请求(例如REST),那么MySQL至少需要同时打开这么多连接

MySqlConnector连接池将在默认情况下保持这些连接在使用后打开(每个web服务器最多100个连接)

您将得到以下数目的休眠数据库连接(假设每个web服务器上的连接字符串始终保持不变):

但是,保持打开的最大连接数(默认情况下)不会高于:

number-of-webservers * 100
因此,如果您的应用程序并行执行20个请求,每个请求都建立了从API(web服务器)到数据库服务器的数据库连接,那么根据您的API托管场景,将发生以下情况:

  • 3台带负载平衡器的Web服务器:如果您经常运行应用程序,负载平衡器会随着时间的推移将您的请求分发到所有3台Web服务器。因此,3台Web服务器中的每台服务器都会保持大约20个连接打开到您的数据库服务器。只要一次只有一台客户端执行这些请求,您最终会有60个连接同时。如果最多有4个客户端并行运行20个请求,那么随着时间的推移,每个web服务器将有80个连接保持打开状态,因此总共3*80=240个睡眠数据库连接

  • 像AWS Lambda这样的无服务器技术:与上一个示例中的相同适用于AWS Lambda,但web服务器的数量是无限的(理论上)。因此,如果AWS决定将API调用分发到许多不同的web服务器,您可能会很快超过MySQL的设置


如何配置连接池的建议 如果在固定数量的web服务器上运行API,您可能希望保持
Pooling=true
并将
MaxPoolSize
设置为一个值,即
每个客户端的并行请求数*web服务器数
将始终低于,但如果可能,将高于
典型并行客户端数*并行客户端数如果每一个客户端的请求都是不合理的或可能的,则考虑设置<代码>池> = false <代码>或设置<代码> MyPooSList >不高于<代码> Max连接/ Web服务器的数量< /C> > /<
如果在AWS Lambda等无服务器技术上运行API,请将
Pooling=false
MaxPoolSize
设置为某个较低的值和
ConnectionLifeTi
number-of-webservers * 100