【问题标题】:Azure Blob Error: StorageException: The condition specified using HTTP conditional header(s) is not metAzure Blob 错误:StorageException:不满足使用 HTTP 条件标头指定的条件
【发布时间】:2020-09-30 03:51:25
【问题描述】:

所以我有一个函数,它只是每 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 azure 存储 sdk 中有一个 OperationContext,我可以使用操作上下文作为参数调用 .downloadText()。我只是不确定如何处理 OperationContext。

【问题讨论】:

  • 在下载操作运行时,blob 的内容是否可能发生了变化?
  • 是的,当然。

标签: azure http azure-storage azure-blob-storage azure-java-sdk


【解决方案1】:

首先,我建议您在此处阅读有关 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 标头中的第二个操作。

现在在第 1 次和第 2 次操作之间,blob 发生了一些变化,导致 etag 值发生变化。由于第二个请求仍然使用旧的 etag 值并且 etag 之间存在不匹配,因此您的请求失败并显示 precondition failedif-match 标头中存在 etag 指示存储服务仅在条件匹配(即 etag 匹配)时执行操作。由于 etag 不匹配,您会收到此错误。

要解决此问题,您需要使用以下 downloadText() 方法的覆盖:

downloadText(final String charsetName, final AccessCondition accessCondition, BlobRequestOptions options, OperationContext opContext)

并为if-match 指定一个带有“*”值的访问条件,这实际上告诉存储服务忽略etag 值。您可以在此处了解有关访问条件的更多信息:https://docs.microsoft.com/en-us/java/api/com.microsoft.azure.storage.accesscondition?view=azure-java-legacy

您的代码将类似于(未经测试的代码):

AccessCondition accessCondition = AccessCondition.generateIfMatchCondition("*");

并在您的 downloadText() 方法中使用此访问条件。

【讨论】:

  • 我遇到了同样的问题,但问题是我正在使用 BlobTrigger。在这种情况下我们可以做这个 if-match 吗?
猜你喜欢
  • 2011-07-02
  • 2021-06-16
  • 2017-04-21
  • 2011-09-01
  • 2018-10-18
  • 2013-10-21
  • 2016-08-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多