【问题标题】:Creating Azure blob containers from a powershell cmdlet fails从 PowerShell cmdlet 创建 Azure Blob 容器失败
【发布时间】:2020-04-30 18:09:14
【问题描述】:

我有一小段 C# 代码可以在通过控制台模式可执行文件运行时创建 Azure Blob 容器,但当相同的代码是 PowerShell cmdlet 的一部分(也在 C# 中)时会失败。失败模式真的很奇怪:它创建了容器,然后在出错之前不断重试几分钟。没看懂。

使用 .NET Framework 4.8 和 Azure.Storage.Blobs v12.4.1 在 Visual Studio 中构建的代码:

using System.Management.Automation;
using Azure.Storage.Blobs;
using Azure.Storage.Blobs.Models;

namespace BlobTest.Commands
{
    [Cmdlet(VerbsData.Initialize, "AzContainer")]
    public class Initialize_AzContainer : Cmdlet
    {
        protected override void ProcessRecord()
        {
            base.ProcessRecord();

            const string AzStorageAccount = "stevestorageaccount";
            const string AzAccessKey = "*****==";

            string connectionString = $"DefaultEndpointsProtocol=http" // http intentional: for wireshark
                                      + $";AccountName={AzStorageAccount}"
                                      + $";AccountKey={AzAccessKey}"
                                      + ";EndpointSuffix=core.windows.net";

            const string containerName = "my-test-container-2";

            var bsclient = new BlobServiceClient(connectionString);

            WriteVerbose($"Creating container {containerName}");
            var rc = bsclient.CreateBlobContainer(containerName, PublicAccessType.None);

            WriteVerbose($"Result = {rc}");
        }
    }
}

这会在呕吐前挂起几分钟:

PS> Import-Module .\BlobTest.Commands.dll
PS> Initialize-AzContainer -Verbose
VERBOSE: Creating container my-test-container-2

[hung out for 7 minutes]

Initialize-AzContainer : Retry failed after 6 tries.
At line:1 char:1
+ Initialize-AzContainer -Verbose
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [Initialize-AzContainer], AggregateException
    + FullyQualifiedErrorId : System.AggregateException,BlobTest.Commands.Initialize_AzContainer

我在进行故障排除时故意使用不安全的 http,以便我可以嗅探对话,而 Wireshark 表现出非常奇怪的行为。痕迹中的// 是我的笔记,不是痕迹的一部分:

// MY END SENDS: this looks normal
PUT /my-test-container-2?restype=container HTTP/1.1
x-ms-version: 2019-07-07
x-ms-client-request-id: acc4991b-33ab-4764-9f20-a33edb5cc4a3
x-ms-return-client-request-id: true
User-Agent: azsdk-net-Storage.Blobs/12.4.1 (.NET Framework 4.8.4150.0; Microsoft Windows 10.0.18363 )
x-ms-date: Wed, 29 Apr 2020 17:42:27 GMT
Authorization: SharedKey <secret key info>
Host: stevestorageaccount.blob.core.windows.net
Content-Length: 0

// AZURE REPLIES: all ok!
HTTP/1.1 201 Created
Content-Length: 0
Last-Modified: Wed, 29 Apr 2020 17:42:28 GMT
ETag: "0x8D7EC64AF7BD68A"
Server: Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
x-ms-request-id: 5ebb740e-201e-001a-354d-1e15bd000000
x-ms-client-request-id: acc4991b-33ab-4764-9f20-a33edb5cc4a3
x-ms-version: 2019-07-07
Date: Wed, 29 Apr 2020 17:42:27 GMT

// MY END TRIES AGAIN - huh?
PUT /my-test-container-2?restype=container HTTP/1.1
x-ms-version: 2019-07-07
x-ms-client-request-id: acc4991b-33ab-4764-9f20-a33edb5cc4a3
x-ms-return-client-request-id: true
User-Agent: azsdk-net-Storage.Blobs/12.4.1 (.NET Framework 4.8.4150.0; Microsoft Windows 10.0.18363 )
x-ms-date: Wed, 29 Apr 2020 17:42:29 GMT
Authorization: SharedKey <secret key info>
Host: stevestorageaccount.blob.core.windows.net
Content-Length: 0

// AZURE REPLIES: sorry already exists
HTTP/1.1 409 The specified container already exists.
Content-Length: 230
Content-Type: application/xml
Server: Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
x-ms-request-id: 5ebb7805-201e-001a-224d-1e15bd000000
x-ms-client-request-id: acc4991b-33ab-4764-9f20-a33edb5cc4a3
x-ms-version: 2019-07-07
x-ms-error-code: ContainerAlreadyExists
Date: Wed, 29 Apr 2020 17:42:29 GMT
...<?xml version="1.0" encoding="utf-8"?>
<Error>
<Code>ContainerAlreadyExists</Code>
<Message>The specified container already exists.
RequestId:5ebb7805-201e-001a-224d-1e15bd000000
Time:2020-04-29T17:42:29.6128339Z</Message></Error>

(repeats a few times)

相同的代码在控制台模式的可执行文件中运行良好,无论我使用async 还是如上所述的常规同步,它的行为方式都相同。我尝试了各种其他组合,添加取消令牌等,但没有任何影响。

注意:我知道如何使用本机 Azure cmdlet 创建容器,但以上是附加处理的一部分,所以我试图找出故障的根源,而不是找到其他方法来创建容器.

我在这方面花了好几个小时,不知道发生了什么。

编辑:我已经尝试重新启动我的系统,没有任何区别,这就是 Windows 10 上的 PowerShell 5.1.18362.752 以及所有最新更新。

【问题讨论】:

    标签: c# azure azure-blob-storage


    【解决方案1】:

    这里似乎触发了retry policy。但奇怪的是,在控制台项目中,运行成功是不会重试的。

    作为一种解决方法,您可以在您的代码中设置重试策略,示例代码如下:

    [Cmdlet(VerbsData.Initialize, "AzContainer")]
    public class Initialize_AzContainer : Cmdlet
    {
        protected override void ProcessRecord()
        {
            base.ProcessRecord();
    
           //other code
    
           //set the retry policy here
            var options = new BlobClientOptions();
            options.Retry.MaxRetries = 0;
    
            var bsclient = new BlobServiceClient(connectionString, options);
    
            WriteVerbose($"Creating container {containerName}");
    
            var rc = bsclient.CreateBlobContainer(containerName, PublicAccessType.None);
            WriteVerbose($"Result = {rc}");
    
    
        }
    
    }
    

    【讨论】:

    • 不出所料,这没有帮助;将 Retries 设置为较低的数字只会使其失败更快,设置为零会导致加载失败,“找不到 System.Buffers 版本 4.0.2.0 或其依赖项之一”。我认为这里发生的情况是,所有这些 Azure 东西所需的 DLL 与 PowerShell 首先加载的任何 DLL 都不兼容,并且没有解决方法。我不能在 PowerShell cmdlet 中使用实体框架。参考:stackoverflow.com/questions/59258265/…
    • 这似乎很可能是一个死胡同,或者至少很脆弱 - 在下一次更新中打破 - 我决定放弃 cmdlet 的想法,只构建我自己的 .EXE(就像我做的那样与实体框架的东西)。欣赏洞察力。
    猜你喜欢
    • 1970-01-01
    • 2020-09-15
    • 1970-01-01
    • 2011-02-24
    • 2020-06-25
    • 2021-11-18
    • 1970-01-01
    • 2018-06-12
    • 2023-03-11
    相关资源
    最近更新 更多