Google 云存储 - 将大对象重写到 "nearline" 存储桶时出现 SocketTimeoutException

Google Cloud Storage - SocketTimeoutException when rewriting a big object to "nearline" bucket

环境:
Java 客户端 ("google-api-services-storage", "v1-rev33-1.20.0") 使用 JSON API (com.google.api.services.storage.Storage class).

目标:
使用 Java 客户端将大对象从 "standard" 移动到 "nearline" 存储桶(文件大小为 512 MB)。

步骤:
使用 "rewrite" API 方法。

问题:
我在 20 秒内收到 SocketTimeoutException。

调查:
当我使用从 "standard" 桶重写到同一对象的另一个 "standard" 桶时,相同的代码工作正常。
我还尝试了 APIs Explorer 并创建了一个将对象从 "standard" 重写到 "nearline" 存储桶的请求。服务器在大约 27 秒内响应,响应中的 "totalBytesRewritten" 属性 大约是文件大小的一半。如何获取和处理这样的响应?
文档说:
"If the source and destination are different locations and/or storage classes, the rewrite method might require multiple calls."

我的代码(Java):

final Storage.Objects.Rewrite rewriteRequest = storage.objects().rewrite(
       STANDARD_BUCKET_NAME,
       SOURCE_OBJECT_PATH,
       NEARLINE_BUCKET_NAME,
       TARGET_OBJECT_PATH,
       null // no metadata overriding
);

rewriteRequest.execute();

请帮忙

根据 documentation,如果文件被分割成块,您应该再次调用 rewrite,使用 rewrite 的第一个响应中返回的 'rewriteToken'。操作将恢复,再处理一大块数据。这应该重复直到响应有 getDone() == true。

我对 java api 的实现:

private void rewriteUntilDone(final String sourceBucket, final String sourceKey,
                              final String destBucket,  final String destKey) throws IOException {
    rewriteUntilDone(sourceBucket, sourceKey, destBucket, destKey, null);
}

private void rewriteUntilDone(final String sourceBucket, final String sourceKey,
                              final String destBucket, final String destKey,
                              @Nullable final String rewriteToken)
        throws IOException {

    Storage.Objects.Rewrite rewrite = googleStorage.objects().rewrite(sourceBucket, sourceKey, destBucket, destKey, null);
    if (rewriteToken != null) {
        rewrite.setRewriteToken(rewriteToken);
    }
    RewriteResponse rewriteResponse = rewrite.execute();

    if (!rewriteResponse.getDone()) {
        String rewriteToken2 = rewriteResponse.getRewriteToken();
        BigInteger totalBytesRewritten = rewriteResponse.getTotalBytesRewritten();
        log.debug("Rewriting not finished, bytes completed: {}. Calling rewrite again with token {}", totalBytesRewritten, rewriteToken2);
        rewriteUntilDone(sourceBucket, sourceKey, destBucket, destKey, rewriteToken2);
    }
}

编辑: 此外,您可能必须增加读取超时。似乎重写在 27 秒后响应,但默认超时为 20 秒。 Wrap your GoogleCredentials to set the read timeout