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

ran*_*ndy 5 sql-server azure azure-sql-database azure-managed-identity

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

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

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

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;
Run Code Online (Sandbox Code Playgroud)

当我查看会话计数时,每次我点击该页面,它都会增加 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
Run Code Online (Sandbox Code Playgroud)

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

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

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

-兰迪

mpe*_*son 2

如果您在每个请求上创建一个新的DBContext,并且它credential.GetToken(...)在构造函数中调用,那么您很可能每次都会得到不同的令牌,因此无法池化连接。

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