写入CloudAppendBlob:远程服务器返回错误:(409)冲突和ProcessExpectedStatusCodeNoException

时间:2018-08-23 15:54:24

标签: c# azure azure-storage azure-storage-blobs

我试图了解导致远程服务器返回错误的原因:(409)冲突

我正在通过获取租约,追加文本并打破租约的方式将行写到AppendBlob。该错误只会偶尔发生,所以我很好奇什么情况会导致它发生。我的怀疑是,如果多个用户访问该代码执行的端点,并且以某种方式一次调用获取租约的事件同时发生,则可能会发生。

// Get the AppendBlob reference
CloudAppendBlob blob = ….

// Acquire a lease on the blob until a call to breaking the lease is made
string leaseId = Guid.NewGuid().ToString();
await blob.AcquireLeaseAsync(null, leaseId);

// Append a new entry to the blob
await blob.AppendTextAsync(
       textToBeAppended,
       Encoding.UTF8,
       new AccessCondition { LeaseId = leaseId },
       new BlobRequestOptions(),
       new OperationContext());

// break the lease on the blob
await blob.BreakLeaseAsync(null);

失败的方法是 Microsoft.WindowsAzure.Storage.Shared.Protocol.HttpResponseParsers.ProcessExpectedStatusCodeNoException。

从遥测中我看到,对Blob上的PUT的调用最初失败,并显示409状态码和上述异常,但在成功地执行202结果码的PUT调用后立即发生。我假设Azure存储正在重试,但是我看不到应该附加到文件中的文本行。

如果有帮助,这里是完整的调用堆栈,我不确定此堆栈跟踪中的ProcessExpectedStatusCodeNoException的含义。

  

Microsoft.WindowsAzure.Storage.StorageException:在   Microsoft.WindowsAzure.Storage.Core.Executor.Executor.EndExecuteAsync   (Microsoft.WindowsAzure.Storage,版本= 9.3.1.0,文化=中性,   PublicKeyToken = 31bf3856ad364e35Microsoft.WindowsAzure.Storage,   版本= 9.3.1.0,文化=中性,PublicKeyToken = 31bf3856ad364e35:   c:\ Program档案   (x86)\ Jenkins \ workspace \ release_dotnet_master \ Lib \ ClassLibraryCommon \ Core \ Executor \ Executor.csMicrosoft.WindowsAzure.Storage,   版本= 9.3.1.0,文化=中性,PublicKeyToken = 31bf3856ad364e35:50)   在   Microsoft.WindowsAzure.Storage.Core.Util.AsyncExtensions + <> c__DisplayClass2`1.b__0   (Microsoft.WindowsAzure.Storage,版本= 9.3.1.0,文化=中性,   PublicKeyToken = 31bf3856ad364e35Microsoft.WindowsAzure.Storage,   版本= 9.3.1.0,文化=中性,PublicKeyToken = 31bf3856ad364e35:   c:\ Program档案   (x86)\ Jenkins \ workspace \ release_dotnet_master \ Lib \ ClassLibraryCommon \ Core \ Util \ AsyncExtensions.csMicrosoft.WindowsAzure.Storage,   版本= 9.3.1.0,文化=中性,PublicKeyToken = 31bf3856ad364e35:69)   在System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw   (mscorlib,版本= 4.0.0.0,文化=中性,   PublicKeyToken = b77a5c561934e089),网址为   System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification   (mscorlib,版本= 4.0.0.0,文化=中性,   PublicKeyToken = b77a5c561934e089),网址为   Microsoft.Community.Data.Providers.BlobStorageProvider + d__1.MoveNext   (Microsoft.Community.Data,版本= 1.0.0.0,文化=中性,   PublicKeyToken = nullMicrosoft.Community.Data,版本= 1.0.0.0,   文化=中性,PublicKeyToken =空:   C:\ BA \ 813 \ s \ Microsoft.Community \ Microsoft.Community.Data \ Providers \ BlobStorageProvider.csMicrosoft.Community.Data,   版本= 1.0.0.0,文化=中性,PublicKeyToken =空:67)在   System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw   (mscorlib,版本= 4.0.0.0,文化=中性,   PublicKeyToken = b77a5c561934e089),网址为   Microsoft.Community.Data.Providers.BlobStorageProvider + d__1.MoveNext   (Microsoft.Community.Data,版本= 1.0.0.0,文化=中性,   PublicKeyToken = nullMicrosoft.Community.Data,版本= 1.0.0.0,   文化=中性,PublicKeyToken =空:   C:\ BA \ 813 \ s \ Microsoft.Community \ Microsoft.Community.Data \ Providers \ BlobStorageProvider.csMicrosoft.Community.Data,   版本= 1.0.0.0,文化=中性,PublicKeyToken =空:72)位于   System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw   (mscorlib,版本= 4.0.0.0,文化=中性,   PublicKeyToken = b77a5c561934e089),网址为   System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification   (mscorlib,版本= 4.0.0.0,文化=中性,   PublicKeyToken = b77a5c561934e089),网址为   Microsoft.Community.Web.Repositories.AzureMLRecommendationsRepository + d__6.MoveNext   (Microsoft.Community.Web,版本= 1.0.0.0,文化=中性,   PublicKeyToken = nullMicrosoft.Community.Web,版本= 1.0.0.0,   文化=中性,PublicKeyToken =空:   C:\ BA \ 813 \ s \ Microsoft.Community \ Microsoft.Community.Web \ Repositories \ AzureMLRecommendationsRepository.csMicrosoft.Community.Web,   版本= 1.0.0.0,文化=中性,PublicKeyToken =空:95)

     

内部异常System.Net.WebException在   Microsoft.WindowsAzure.Storage.Core.Executor.Executor.EndExecuteAsync:   在   Microsoft.WindowsAzure.Storage.Shared.Protocol.HttpResponseParsers.ProcessExpectedStatusCodeNoException   (Microsoft.WindowsAzure.Storage,版本= 9.3.1.0,文化=中性,   PublicKeyToken = 31bf3856ad364e35Microsoft.WindowsAzure.Storage,   版本= 9.3.1.0,文化=中性,PublicKeyToken = 31bf3856ad364e35:   c:\ Program档案   (x86)\ Jenkins \ workspace \ release_dotnet_master \ Lib \ Common \ Shared \ Protocol \ HttpResponseParsers.Common.csMicrosoft.WindowsAzure.Storage,   版本= 9.3.1.0,文化=中性,PublicKeyToken = 31bf3856ad364e35:54)   在   Microsoft.WindowsAzure.Storage.Blob.CloudBlob + <> c__DisplayClass39.b__38   (Microsoft.WindowsAzure.Storage,版本= 9.3.1.0,文化=中性,   PublicKeyToken = 31bf3856ad364e35Microsoft.WindowsAzure.Storage,   版本= 9.3.1.0,文化=中性,PublicKeyToken = 31bf3856ad364e35:   c:\ Program档案   (x86)\ Jenkins \ workspace \ release_dotnet_master \ Lib \ ClassLibraryCommon \ Blob \ CloudBlob.csMicrosoft.WindowsAzure.Storage,   版本= 9.3.1.0,文化=中性,PublicKeyToken = 31bf3856ad364e35:   3830)在   Microsoft.WindowsAzure.Storage.Core.Executor.Executor.EndGetResponse   (Microsoft.WindowsAzure.Storage,版本= 9.3.1.0,文化=中性,   PublicKeyToken = 31bf3856ad364e35Microsoft.WindowsAzure.Storage,   版本= 9.3.1.0,文化=中性,PublicKeyToken = 31bf3856ad364e35:   c:\ Program档案   (x86)\ Jenkins \ workspace \ release_dotnet_master \ Lib \ ClassLibraryCommon \ Core \ Executor \ Executor.csMicrosoft.WindowsAzure.Storage,   版本= 9.3.1.0,文化=中性,PublicKeyToken = 31bf3856ad364e35:   299)

2 个答案:

答案 0 :(得分:1)

我想知道为什么您需要租赁Blob,然后将文本附加到Blob。如果同时有多个编写者,则您将遇到 EXPECTED (您的代码中发生(409)冲突)的情况。

正如您在official doc中看到的那样,当仍通过租约(A)租借一个Blob时获得租约(B)会遇到409错误: enter image description here

基本上,blob租约是为了实现对blob的排他性写访问,如果要同时对多个编写者的blob进行附加,则不宜使用blob租约。

如果从代码中删除了AcquireLease和BreakLease操作,您会担心什么?老实说,我认为没有任何危害。

答案 1 :(得分:0)

听起来像是并发的问题:
如果Blob具有有效租约,则取消租约。租约一旦失效,就无法续签。任何授权的请求都可以中断租约;不需要请求指定匹配的租赁ID。当租约被破坏时,允许租借中断时间段过去,在此期间,除了对租约的破坏和释放外,无法执行任何租借操作。成功解除租约后,响应会以秒为单位显示获取新租约的时间间隔。 https://docs.microsoft.com/en-us/rest/api/storageservices/lease-blob#outcomes-of-use-attempts-on-blobs-by-lease-state


如果您查看上面的链接,将会看到一个巨大的表格,说明如何发生409s。
您可以运行提琴手来获取内部异常的踪迹吗?