从web服务器API并行调用时,快速增加AWS RDS上睡眠的MySQL连接数
我使用的是aspnetboilerplate核心和entityframework核心 我有1个大的请求实体框架核心:从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
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