Azure Blob:“不满足使用 HTTP 条件标头指定的条件" [英] Azure Blob: "The condition specified using HTTP conditional header(s) is not met"
问题描述
我在运行我的应用程序时遇到了这个异常.它也发生在真正的 Azure blob 存储中.
I got this exception when I run my application. It happens also in the real Azure blob storage.
我发现 Fiddler 提出了导致此问题的请求:
I've caught with Fiddler the request that creates this problem:
GET http://127.0.0.1:10000/devstoreaccount1/ebb413ed-fdb5-49f2-a5ac-74faa7e2d3bf/8844c3ec-9e4b-43ec-88b2-58eddf65fc0a/perro?timeout=90 HTTP/1.1
x-ms-version: 2009-09-19
User-Agent: WA-Storage/6.0.6002.18006
x-ms-range: bytes=0-524304
If-Match: 0x8CDA190BD304DD0
x-ms-date: Wed, 23 Feb 2011 16:49:18 GMT
Authorization: SharedKey devstoreaccount1:5j3IScY9UJLN3o1ICWKwVEazO4/IDJG796sdZKqHlR4=
Host: 127.0.0.1:10000
这是回应:
HTTP/1.1 412 The condition specified using HTTP conditional header(s) is not met.
Content-Length: 252
Content-Type: application/xml
Server: Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
x-ms-request-id: fbff9d15-65c8-4f21-9088-c95e4496c62c
x-ms-version: 2009-09-19
Date: Wed, 23 Feb 2011 16:49:18 GMT
<?xml version="1.0" encoding="utf-8"?><Error><Code>ConditionNotMet</Code><Message>The condition specified using HTTP conditional header(s) is not met.
RequestId:fbff9d15-65c8-4f21-9088-c95e4496c62c
Time:2011-02-23T16:49:18.8790478Z</Message></Error>
当我使用从这一行检索到的 Stream 时会发生这种情况:
It happens when I use the Stream retrieved from this line:
blob.OpenRead();
为什么 ETAG 会在读取操作中进行处理?我怎样才能避免这个问题?
Why the ETAG minds in a read operation? How may I avoid this problem?
每次我在 blob 存储上启动多个并行任务时都会发生这种情况.
It happens every time I launch several parallel tasks doing things on the blob storage.
如果我使用:
blob.OpenRead(new BlobRequestOptions() { AccessCondition = AccessCondition.IfMatch("*") });
我得到了这个没有内部异常的异常(在它有一个带有详细信息的 WebException 之前),要么是 Fiddler 中的失败行:
I got this exception with no inner one (before it had a WebException with the details), either a fail line in Fiddler :
Microsoft.WindowsAzure.StorageClient.StorageClientException was unhandled
Message=The conditionals specified for this operation did not match server.
Source=mscorlib
StackTrace:
Server stack trace:
at Microsoft.WindowsAzure.StorageClient.Tasks.Task`1.get_Result()
at Microsoft.WindowsAzure.StorageClient.Tasks.Task`1.ExecuteAndWait()
at Microsoft.WindowsAzure.StorageClient.TaskImplHelper.ExecuteImpl[T](Func`2 impl)
at Microsoft.WindowsAzure.StorageClient.BlobReadStream.Read(Byte[] buffer, Int32 offset, Int32 count)
at System.IO.BinaryReader.ReadBytes(Int32 count)
at System.Runtime.Serialization.Formatters.Binary.SerializationHeaderRecord.Read(__BinaryParser input)
at System.Runtime.Serialization.Formatters.Binary.__BinaryParser.ReadSerializationHeaderRecord()
at System.Runtime.Serialization.Formatters.Binary.__BinaryParser.Run()
at System.Runtime.Serialization.Formatters.Binary.ObjectReader.Deserialize(HeaderHandler handler, __BinaryParser serParser, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage)
at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream, HeaderHandler handler, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage)
...........
提前致谢.
推荐答案
Bufff... 谜团解决了!
Bufff... mistery solved!
好吧,当您执行 CloudBlob.OpenRead()
时,客户端库会执行两个操作:
Well, when you do a CloudBlob.OpenRead()
, the client library is doing two operations:
首先获取blob块列表:
First, get the blob block list:
GET /devstoreaccount1/etagtest/test2.txt?comp=blocklist&blocklisttype=Committed&timeout=90 HTTP/1.1
x-ms-version: 2009-09-19
User-Agent: WA-Storage/6.0.6002.18006
x-ms-date: Wed, 23 Feb 2011 22:21:01 GMT
Authorization: SharedKey devstoreaccount1:SPOBe/IUrZJvoPXnAdD/Twnppvu37+qrUbHnaBHJY24=
Host: 127.0.0.1:10000
HTTP/1.1 200 OK
Transfer-Encoding: chunked
Content-Type: application/xml
Last-Modified: Wed, 23 Feb 2011 22:20:33 GMT
ETag: 0x8CDA1BF0593B660
Server: Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
x-ms-request-id: ecffddf2-137f-403c-9595-c8fc2847c9d0
x-ms-version: 2009-09-19
x-ms-blob-content-length: 4
Date: Wed, 23 Feb 2011 22:21:02 GMT
注意响应中的 ETag.
Attention to the ETag in the response.
第二,我猜开始检索它,现在注意请求中的ETag:
Second, I guess that start to retrieve it, and now attention to the ETag in the request:
GET /devstoreaccount1/etagtest/test2.txt?timeout=90 HTTP/1.1
x-ms-version: 2009-09-19
User-Agent: WA-Storage/6.0.6002.18006
x-ms-range: bytes=0-525311
If-Match: 0x8CDA1BF0593B660
x-ms-date: Wed, 23 Feb 2011 22:21:02 GMT
Authorization: SharedKey devstoreaccount1:WXzXRv5e9+p0SzlHUAd7iv7jRHXvf+27t9tO4nrhY5Q=
Host: 127.0.0.1:10000
HTTP/1.1 206 Partial Content
Content-Length: 4
Content-Type: text/plain
Content-Range: bytes 0-3/4
Last-Modified: Wed, 23 Feb 2011 22:20:33 GMT
ETag: 0x8CDA1BF0593B660
Server: Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
x-ms-request-id: db1e221d-fc61-4837-a255-28b1547cb5d7
x-ms-version: 2009-09-19
x-ms-lease-status: unlocked
x-ms-blob-type: BlockBlob
Date: Wed, 23 Feb 2011 22:21:02 GMT
如果另一个 WebRole 在调用之间的 blob 中执行某些操作,会发生什么情况?是竞争条件.
What happen if another WebRole do something in the blob between call? YES a race condition.
解决方案:使用CloudBlob.DownloadToStream()
,该方法只发出一次调用:
Solution: Use CloudBlob.DownloadToStream()
, that method only issues one call:
GET /devstoreaccount1/etagtestxx/test2.txt?timeout=90 HTTP/1.1
x-ms-version: 2009-09-19
User-Agent: WA-Storage/6.0.6002.18006
x-ms-date: Wed, 23 Feb 2011 22:34:02 GMT
Authorization: SharedKey devstoreaccount1:VjXIO2kbjCIP4UeiXPtxDxmFLeoYAKOqiRv4SV3bZno=
Host: 127.0.0.1:10000
HTTP/1.1 200 OK
Content-Length: 4
Content-Type: text/plain
Last-Modified: Wed, 23 Feb 2011 22:33:47 GMT
ETag: 0x8CDA1C0DEB562D0
Server: Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
x-ms-request-id: 183a05bb-ea47-4811-8768-6a62195cdb64
x-ms-version: 2009-09-19
x-ms-lease-status: unlocked
x-ms-blob-type: BlockBlob
Date: Wed, 23 Feb 2011 22:34:02 GMT
明天早上我会在工作中练习这个,看看会发生什么.
I will put this on practice tomorrow morning at work and see what happen.
这篇关于Azure Blob:“不满足使用 HTTP 条件标头指定的条件"的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!