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

时间:2021-05-04 12:39:53

标签: sql-server azure azure-sql-database azure-managed-identity

EF Core 连接池似乎无法与用户分配的托管标识一起正常工作。我的网页从我的 Angular 前端到 Web API 控制器进行了 3 次 Ajax 调用。控制器使用包含实现 DbContextIDisposable 的存储库类。

我们使用默认依赖容器和默认 DbContext 设置运行带有 EF Core 的 .NET Core 3.1,所以它是 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 Server 身份验证时,它按预期工作。

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

-兰迪

1 个答案:

答案 0 :(得分:0)

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

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