Azure SQL 数据库连接池与用户分配的托管标识

Azure SQL Database Connection Pooling with User Assigned Managed Identity

似乎 EF Core 连接池无法与用户分配的托管标识一起正常工作。我的网页从我的 Angular 前端向 Web API 控制器发出 3 Ajax 次调用。控制器使用包含实现 IDisposable.

DbContext 的存储库 class

我们是 运行 .NET Core 3.1 和 EF Core 使用默认的依赖容器和默认的 DbContext 设置,所以它是 ServiceLifeTime.Scoped.

我的 DbContext ctor 有这样的托管身份代码。

var connection = (Microsoft.Data.SqlClient.SqlConnection)Database.GetDbConnection();

var options = new DefaultAzureCredentialOptions { ManagedIdentityClientId = surveyToolOptions.Value.ManagedIdentityClientId };
var credential = new DefaultAzureCredential(options);
var token = credential.GetToken(new Azure.Core.TokenRequestContext(new[] { "https://database.windows.net/.default" }));

connection.AccessToken = token.Token;

当我查看会话计数时,每次我点击该页面时它都会增加 3 个连接。它从不重用连接。他们也不会离开大约 4-5 分钟。

SELECT host_name, Program_name, COUNT(*) 
FROM sys.dm_exec_sessions  s
JOIN sys.databases AS d ON s.database_id = d.database_id
GROUP BY host_name, Program_name

这是一个问题,因为 Azure SQL 数据库的会话数非常有限。 https://docs.microsoft.com/en-us/azure/azure-sql/database/resource-limits-dtu-single-databases#standard-service-tier

当我将它切换到使用用户 ID 和密码的标准 SQL 服务器身份验证时,它按预期工作。

使用托管身份时是否需要关闭连接池?这似乎确实有效,但我确信建立与池关闭的连接需要更长的时间。

-兰迪

如果您在每个请求上创建一个新的 DBContext,并且它在构造函数中调用 credential.GetToken(...),您很可能每次都以不同的标记结束,因此连接无法被合并.

在构造函数外部检索和存储令牌应该可以解决此问题。