Azure Functions static SqlConnection - 正确的扩展方式?

Azure Functions static SqlConnection - right way to scale?

我将 Azure Functions 与队列触发器一起用于我们的部分工作负载。特定函数查询数据库,这会导致缩放问题,因为大量并发函数实例对数据库执行 ping 操作会导致允许的最大 Azrue 数据库连接数不断被命中。

本文 https://docs.microsoft.com/en-us/azure/azure-functions/manage-connections 将 HttpClient 列为应设为静态的资源之一。 是否也应该使用静态 SqlConnection 将数据库访问设为静态以解决此问题,或者通过保持常量连接对象会导致其他一些问题?

Should database access also be made static with static SqlConnection

绝对不是。每个函数调用都应在 using 块中打开一个具有相同连接字符串的新 SqlConnection。运行时将对您的应用程序的单个实例进行多少次并发函数调用并不是很清楚。但是如果它大于 1,那么单例 SqlConnection 就是一件坏事。

我想知道您在 SQL 数据库中究竟遇到了哪个 limit,连接限制还是并发请求限制?在任何一种情况下,我(不是函数专家)都对您获得如此多的并发函数调用感到有点惊讶,所以可能还有其他事情正在发生。就像你在泄漏 SqlConnections。

但是阅读函数文档,我的猜测是函数运行时通过启动函数应用程序的多个实例来扩展。您的 .NET 应用程序可以在单个进程中扩展,但这显然不是 Functions 的工作方式。 Functions 应用程序的每个实例都有自己的 SQL 服务器连接池,默认情况下每个连接池可以有 100 个连接。

也许如果您严格限制连接字符串中的最大池大小,就不会打开那么多连接。当您达到最大池大小时,对 SqlConnection.Open() 的新调用将阻塞长达 30 秒,等待池化的 SqlConnection 变得可用。因此,这不仅限制了应用程序每个实例的连接使用,还限制了负载下的吞吐量。

您可以使用 host.json to control the level of concurrency your functions execute at per instance and the max scaleout 设置中的配置设置来控制您向外扩展的实例数。这将让您控制数据库的总负载量。

对于未来的读者,the documentation has been updated with some information about the SQL connection声明:

Your function code may use the .NET Framework Data Provider for SQL Server (SqlClient) to make connections to a SQL relational database. This is also the underlying provider for data frameworks that rely on ADO.NET, such as Entity Framework. Unlike HttpClient and DocumentClient connections, ADO.NET implements connection pooling by default. However, because you can still run out of connections, you should optimize connections to the database. For more information, see SQL Server Connection Pooling (ADO.NET).

所以,,你不应该让你的 SqlConnection 静态。