Authentication to Azure Storage Account and Azure Service Bus using managed identity takes longer than using connection string

huangapple go评论80阅读模式
英文:

Authentication to Azure Storage Account and Azure Service Bus using managed identity takes longer than using connection string

问题

我有一个简单的Azure函数,它在Service Bus队列上触发,从存储帐户下载数据,执行一些简单的逻辑,然后将消息发送到另一个Service Bus队列。
函数以前使用连接字符串(共享访问密钥)进行身份验证。
为了遵循最佳实践和建议,我将身份验证方法更改为托管标识。
在这个更改之后,我注意到性能显著下降=>从存储帐户下载数据并将消息发送到队列需要的时间增加了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);
}

有人知道这里可能有什么问题吗?

图像参考

英文:

I have a simple Azure function that got triggered on Service Bus Queue, downloads data from Storage Account, performs some simple logic and sends message to another Service Bus Queue.
Function was using connection strings (Shared Access Key) to authenticate.
To follow best practices and recommendations I changed the authentication method to be managed identity.
After this change, I noticed a significant decrease in performance = > download data from storage account and send message to queue takes 2.5 times longer.

As an example I created two simple functions. Both got triggered from service bus queue and download content from blob, the only difference is authentication method. Runtime of the first one is significantly less that second one.

 [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);
    }

Does someone have any idea what might be wrong here?

答案1

得分: 0

通常来说,预计托管标识授权所需的时间会比连接字符串长,因为客户端和服务都需要与 AAD 协调,而连接字符串完全由存储本身验证。

因为您在每次调用函数时都在创建您的 BlobServiceClientDefaultAzureCredential,所以您需要在每次调用时支付获取令牌和授权的成本。Azure SDK 的指导建议将客户端视为单例。(参见:Azure SDK .NET 客户端的生命周期管理)这样做可以减少需要进行身份验证和授权的次数,避免频繁支付这个成本。

推荐的方法是使用 Azure Functions 的依赖注入,并使用 Azure Blob 存储包定义的 AddBlobServiceClient 扩展。或者,您可以在函数类的一部分创建 BlobServiceClient 的静态实例 - 尽管随着时间的推移,这可能会变得效率较低。

英文:

Generally speaking, it is expected that managed identity authorization takes longer than a connection string, as both the client and service have to coordinate with AAD, where a connection string is validated entirely by Storage itself.

Because you are creating your BlobServiceClient and DefaultAzureCredential on each invocation of the function, you're paying the cost to acquire the token and authorize on each call. Azure SDK guidance encourages treating clients as singletons. (see: Lifetime management for Azure SDK .NET clients) Doing so would reduce the number of times that you need to authenticate and authorize, avoiding the need to pay that cost so frequently.

The recommended approach would be to use Dependency injection for Azure Functions with the AddBlobServiceClient extension defined by the Azure Blob Storage package. Alternately, you could create a static instance of the BlobServiceClient as part of your function class - though you are likely to see that be less efficient over time.

huangapple
  • 本文由 发表于 2023年6月18日 22:43:13
  • 转载请务必保留本文链接:https://go.coder-hub.com/76501095.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定