因此,我有一个功能,每10分钟简单地从blob存储中下载文本并检查结果。此功能可以运行几天。但是它经常(大约每天)失败,然后出现以下错误。
原因:com.microsoft.azure.storage.StorageException:不满足使用HTTP条件标头指定的条件。
我的代码很简单。
public String downloadTextBlob(CloudBlobDirectory dir, String filename) {
try {
return dir.getBlockBlobReference(filename).downloadText();
} catch (StorageException | IOException | URISyntaxException e) {
throw new WorkbenchRuntimeException(e.getMessage(), e);
}
}
我在here上发布了相同的问题,并且我对回答有关使用OperationContext修复该问题的答案很感兴趣。但是问题不在Java上,答案也没有真正解释它的实际作用。
这里是建议的解决方案(非Java代码)
OperationContext context = new OperationContext();
context.SendingRequest += (sender, e) => {
e.Request.Headers["if-match"] = "*";
};
任何人都可以解释这实际上在做什么吗?也许我可以在Java中复制它,我注意到Java天蓝色存储sdk中有一个OperationContext,并且可以使用操作上下文作为参数来调用.downloadText()。我只是不确定该如何处理OperationContext。
首先,我鼓励您在这里阅读有关Azure Blob存储中的条件标头的信息:https://docs.microsoft.com/en-us/rest/api/storageservices/specifying-conditional-headers-for-blob-service-operations。
我尚未查看Java SDK的源代码,但我的猜测是downloadText()
操作正在幕后执行多项操作。在第一个操作中,它获取Blob的属性(例如Blob的长度等),而在下一个操作中,它实际上是在下载Blob。作为第一个操作的一部分,它还会获取blob的etag,并将相同的etag传递给if-match
标头中的第二个操作。
现在在第一个操作和第二个操作之间,使用blob进行了某些更改,从而导致etag值更改。由于第二个请求仍使用旧的etag值,并且etag之间不匹配,因此您的请求失败,并显示precondition failed
。 if-match
标头中存在etag会指示存储服务执行条件匹配(即etag匹配)的操作[[仅在。由于etag不匹配,您将收到此错误。
downloadText()
方法的替代:并且为downloadText(final String charsetName, final AccessCondition accessCondition, BlobRequestOptions options, OperationContext opContext)
指定一个带有“ *”值的访问条件,这实际上告诉存储服务忽略etag值。您可以在此处了解有关访问条件的更多信息:if-match
。
您的代码将类似于(未经测试的代码):
并在您的downloadText()方法中使用此访问条件。