我有一个简单的Azure函数,它在服务总线队列上触发,从存储帐户下载数据,执行一些简单的逻辑,并将消息发送到另一个服务总线队列。函数正在使用连接字符串(共享访问密钥)进行身份验证。为了遵循最佳实践和建议,我将身份验证方法更改为托管身份。在此更改之后,我注意到性能显著下降= >从存储帐户下载数据并将消息发送到队列所需时间延长了2.5倍。
作为一个例子,我创建了两个简单的函数。两者都是从服务总线队列触发,从blob下载内容,唯一的区别是身份验证方法。第一个的运行时间显著小于第二个。
[FunctionName("TestFuncWithConnString")]
public async Task Run(
[ServiceBusTrigger("testconstring", Connection = "ServiceBusConnectionString")] ServiceBusReceivedMessage message,
ServiceBusMessageActions messageActions)
{
var storageConnectionString = _configuration.GetConnectionString("StorageConnectionString");
var blobContainerClient = new BlobContainerClient(storageConnectionString, "containerName");
var blobClient = blobContainerClient.GetBlobClient("XXX");
var blobMessage = await blobClient.DownloadAsync();
await messageActions.CompleteMessageAsync(message);
}
[FunctionName("TestFuncWithManagedIdentity")]
public async Task Run(
[ServiceBusTrigger("testmanagedidentity ", Connection = "SBNamespaceFQName")] ServiceBusReceivedMessage message,
ServiceBusMessageActions messageActions)
{
var storageConnectionString = new Uri($"https://{StorageAccount}.blob.core.windows.net/");
var blobServiceClient = new BlobServiceClient(storageConnectionString, new DefaultAzureCredential());
var blobContainerClient = blobServiceClient.GetBlobContainerClient("containerName");
var blobClient = blobContainerClient.GetBlobClient("XXX");
var blobMessage = await blobClient.DownloadAsync();
await messageActions.CompleteMessageAsync(message);
}
有谁知道这里出了什么问题吗?
1条答案
按热度按时间mi7gmzs61#
一般来说,托管身份授权所花费的时间应该比连接字符串更长,因为客户端和服务都必须与AAD协调,而AAD中连接字符串完全由存储本身验证。
因为每次调用函数时都要创建
BlobServiceClient
和DefaultAzureCredential
,所以每次调用都要为获取令牌和授权支付成本。Azure SDK指南鼓励将客户端视为单例。* (请参阅:Lifetime management for Azure SDK .NET clients)* 这样做将减少您需要进行身份验证和授权的次数,避免了频繁地支付该费用。推荐的方法是使用Dependency injection for Azure Functions和Azure Blob Storage包定义的AddBlobServiceClient扩展。或者,您可以创建
BlobServiceClient
的静态示例作为函数类的一部分,尽管随着时间的推移,您可能会看到效率越来越低。