Azure Function 输入和输出绑定对象在每个请求中共享或创建
Azure Function input and output binding object are Shared or created in each request
我正在使用 Azure 功能:计时器触发器和 Cosmos DB 提要触发器。
定时触发功能
我在 Timer Trigger 函数中有 Cosmos DB 的输出绑定。我正在创建与服务总线客户端的连接并批量读取消息并在 Cosmos DB 中上传,如下所示。我的问题是每个运行时都会创建 Cosmos DB 连接吗?如果是,我如何共享连接?我怎样才能改进 SB 连接,以便每次运行时它都不会创建新连接。 我在性能方面做得对吗?
Cosmos DB 源触发器
在这个函数中,我将 Cosmos DB 作为触发器并使用 SB 出站。
对于每个请求,都会创建新连接,或者函数会为 Cosmos 和 SB 连接重用现有对象?
据我所知,推荐三种在服务器上的函数之间共享昂贵数据以提高性能的方法:
使用静态客户端变量:每次函数调用都会重复使用静态变量,而不是创建一个新变量,这节省了内存和提供性能优势。当负载较小时,仅在后台为函数创建一个服务器实例,因此静态变量可重复用于同一服务器实例中的多个函数调用。但是如果创建了多个服务器,每个服务器实例都会有自己的静态变量,这些变量将被在同一个服务器实例中处理的函数调用重用。这仍然比每次调用都创建一个新连接要好得多。
查看 this 详细博客,了解 性能负载测试 证明。
使用 MemoryCache:这将允许您在函数之间共享缓存。例如:
static MemoryCache memoryCache = MemoryCache.Default;
public static async Task<object> Run(HttpRequestMessage req, TraceWriter log)
{
var cacheObject = memoryCache["cachedCount"];
var cachedCount = (cacheObject == null) ? 0 : (int)cacheObject;
memoryCache.Set("cachedCount", ++cachedCount, DateTimeOffset.Now.AddMinutes(5));
log.Info($"Webhook triggered memory count {cachedCount}");
return ...
}
这里的代码试图在缓存中找到计数,递增它,并在五分钟内保存它。如果我们将相同的代码复制到同一个 Azure Function App 中的两个函数,那么可以肯定的是,他们每个人都可以看到另一个人设置的计数。请注意,每次您编辑代码时,此缓存都会丢失其内容。
查看 this 博客了解更多详细信息。
使用依赖注入:使用DI创建Singleton实例并使用它们。查看 Use dependency injection in .NET Azure Functions. ServiceBusClient can be registered for dependency injection with the ServiceBusClientBuilderExtensions.
注意:如果静态客户端实现了 IDisposable 接口,则静态客户端的处理将由 .NET 核心运行时自动完成。不要手动处理它,否则它不会被重复使用。此外,确保静态客户端 线程安全 。正如 MS Doc 所说:
Establishing a connection is an expensive operation that you can avoid
by reusing the same factory and client objects for multiple
operations. You can safely use these client objects for concurrent
asynchronous operations and from multiple threads.
安全实例化一次分享ServiceBusClient
.
附加链接:
如果您有任何后续问题,请告诉我。
另一种替代方法是让服务总线触发器并在消息到达时添加文档,而不是执行计时器和处理批处理。这种方法包括以下好处:
- 无需担心代理连接,因为它由 Functions 处理。
- Less/simpler 代码。例如,您可以通过手动反序列化接收反序列化为 POCO w/o 的消息。
- 与事件驱动方法而不是基于时间的批处理保持一致。
我正在使用 Azure 功能:计时器触发器和 Cosmos DB 提要触发器。
定时触发功能
我在 Timer Trigger 函数中有 Cosmos DB 的输出绑定。我正在创建与服务总线客户端的连接并批量读取消息并在 Cosmos DB 中上传,如下所示。我的问题是每个运行时都会创建 Cosmos DB 连接吗?如果是,我如何共享连接?我怎样才能改进 SB 连接,以便每次运行时它都不会创建新连接。 我在性能方面做得对吗?
Cosmos DB 源触发器
在这个函数中,我将 Cosmos DB 作为触发器并使用 SB 出站。 对于每个请求,都会创建新连接,或者函数会为 Cosmos 和 SB 连接重用现有对象?
据我所知,推荐三种在服务器上的函数之间共享昂贵数据以提高性能的方法:
使用静态客户端变量:每次函数调用都会重复使用静态变量,而不是创建一个新变量,这节省了内存和提供性能优势。当负载较小时,仅在后台为函数创建一个服务器实例,因此静态变量可重复用于同一服务器实例中的多个函数调用。但是如果创建了多个服务器,每个服务器实例都会有自己的静态变量,这些变量将被在同一个服务器实例中处理的函数调用重用。这仍然比每次调用都创建一个新连接要好得多。
查看 this 详细博客,了解 性能负载测试 证明。
使用 MemoryCache:这将允许您在函数之间共享缓存。例如:
static MemoryCache memoryCache = MemoryCache.Default; public static async Task<object> Run(HttpRequestMessage req, TraceWriter log) { var cacheObject = memoryCache["cachedCount"]; var cachedCount = (cacheObject == null) ? 0 : (int)cacheObject; memoryCache.Set("cachedCount", ++cachedCount, DateTimeOffset.Now.AddMinutes(5)); log.Info($"Webhook triggered memory count {cachedCount}"); return ... }
这里的代码试图在缓存中找到计数,递增它,并在五分钟内保存它。如果我们将相同的代码复制到同一个 Azure Function App 中的两个函数,那么可以肯定的是,他们每个人都可以看到另一个人设置的计数。请注意,每次您编辑代码时,此缓存都会丢失其内容。
查看 this 博客了解更多详细信息。
使用依赖注入:使用DI创建Singleton实例并使用它们。查看 Use dependency injection in .NET Azure Functions. ServiceBusClient can be registered for dependency injection with the ServiceBusClientBuilderExtensions.
注意:如果静态客户端实现了 IDisposable 接口,则静态客户端的处理将由 .NET 核心运行时自动完成。不要手动处理它,否则它不会被重复使用。此外,确保静态客户端 线程安全 。正如 MS Doc 所说:
Establishing a connection is an expensive operation that you can avoid by reusing the same factory and client objects for multiple operations. You can safely use these client objects for concurrent asynchronous operations and from multiple threads.
安全实例化一次分享ServiceBusClient
.
附加链接:
如果您有任何后续问题,请告诉我。
另一种替代方法是让服务总线触发器并在消息到达时添加文档,而不是执行计时器和处理批处理。这种方法包括以下好处:
- 无需担心代理连接,因为它由 Functions 处理。
- Less/simpler 代码。例如,您可以通过手动反序列化接收反序列化为 POCO w/o 的消息。
- 与事件驱动方法而不是基于时间的批处理保持一致。