我有一小段C#代码,当通过控制台模式可执行文件运行时,可以创建一个Azure Blob容器,但是当同一代码是PowerShell cmdlet(也在C#中)的一部分时,它会失败。故障模式确实很奇怪:它创建了容器,但是在出错之前,它会继续尝试coupla分钟。我不明白。
该代码是在Visual Studio中使用.NET Framework 4.8和Azure.Storage.Blobs v12.4.1构建的:
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}");
}
}
}
这会在发声前悬挂一段coupla分钟:
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以及所有最新更新一起进行。
[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}");
}
}