我们应用程序的一部分通过存储传输服务 API 启动从 Amazon S3 到 Google Cloud Storage 的传输。我们已经成功启动并运行了几个月,直到昨天我们的转移停止工作。我们可以看到在控制台中启动了传输,但它无限期挂起,并显示单个历史记录项:"此传输正在开始..."我们有一个后台进程轮询传输状态,我们看到它返回的状态为"transfer_calculating"
在尝试调试此问题时,我们通过存储控制台设置传输。我们使用了应用程序使用的相同 AWS 访问密钥 ID/秘密访问密钥,并且传输成功完成。这让我们相信问题与传输服务 API 或启动 API 调用的代码无关。
转移作业代码:
TransferJob tjob = new TransferJob()
.setDescription(description)
.setStatus('ENABLED')
.setProjectId(transferGoogleProject)
.setTransferSpec(
new TransferSpec()
.setGcsDataSink(new GcsData().setBucketName(googleStorageBucket))
.setAwsS3DataSource(
new AwsS3Data()
.setBucketName(s3Bucket)
.setAwsAccessKey(new AwsAccessKey().setAccessKeyId(transferAwsKey).setSecretAccessKey(transferAwsSecret)))
.setObjectConditions(new ObjectConditions().setIncludePrefixes(s3Keys))
.setTransferOptions(
new TransferOptions()
.setDeleteObjectsFromSourceAfterTransfer(false)
.setOverwriteObjectsAlreadyExistingInSink(true)
.setDeleteObjectsUniqueInSink(false)))
.setSchedule(
new Schedule()
.setScheduleStartDate(date)
.setScheduleEndDate(date)
.setStartTimeOfDay(time))
tjob = storagetransfer.transferJobs().create(tjob).execute()
库配置:
<dependency>
<groupId>com.google.api-client</groupId>
<artifactId>google-api-client</artifactId>
<version>1.19.1</version>
</dependency>
<dependency>
<groupId>com.google.apis</groupId>
<artifactId>google-api-services-bigquery</artifactId>
<version>v2-rev191-1.19.1</version>
</dependency>
<dependency>
<groupId>com.google.apis</groupId>
<artifactId>google-api-services-storage</artifactId>
<version>v1-rev26-1.19.1</version>
</dependency>
<dependency>
<groupId>com.google.apis</groupId>
<artifactId>google-api-services-storagetransfer</artifactId>
<version>v1-rev3-1.19.1</version>
</dependency>
<dependency>
<groupId>com.google.oauth-client</groupId>
<artifactId>google-oauth-client</artifactId>
<version>1.19.0</version>
</dependency>
<dependency>
<groupId>com.google.http-client</groupId>
<artifactId>google-http-client</artifactId>
<version>1.19.0</version>
</dependency>
<dependency>
<groupId>com.google.http-client</groupId>
<artifactId>google-http-client-jackson2</artifactId>
<version>1.19.0</version>
</dependency>
我们已经在开发环境中将版本提升了 1.21.0,但传输仍然卡在"此传输正在开始..."
在这一点上,我们陷入了困境,还有其他人遇到这个问题吗?
根据 Google 的 @mayur-deshpande 提供的反馈(谢谢!),我们的问题源于传递给 setStartTimeOfDay() 的时间值需要采用 UTC。到目前为止,我们已经使用了美国/太平洋,这在创建传输开发指南的以下代码片段中规定
/**
* Specify times below using US Pacific Time Zone.
*/
private static final String START_DATE = "YYYY-MM-DD";
private static final String START_TIME = "HH:MM:SS";
由于时差,我们发送请求的时间已经过去了,因此传输处于开始状态,直到第二天我们的时间被击中。我们看到这种情况发生,因为请求最终完成。
一天的 setStartTime() 的 javadoc 确实指出了使用 UTC 的必要性:
/**
* The time in UTC at which the transfer will be scheduled to start in a day. Transfers may start
* later than this time. If not specified, transfers are scheduled to start at midnight UTC.
* @param startTimeOfDay startTimeOfDay or {@code null} for none
*/
public Schedule setStartTimeOfDay(TimeOfDay startTimeOfDay)
上面引用的示例代码应反映此要求,因此我将在 github 存储库中提交问题。
此外,由于我们只执行一次传输,因此我们确保将开始时间设置为将来一分钟,以考虑服务器之间的细微时差:
DateTime now = new DateTime().plusMinutes(1)
Date date = new Date().setDay(now.dayOfMonth).setMonth(now.monthOfYear).setYear(now.year)
TimeOfDay time = new TimeOfDay().setHours(now.hourOfDay).setMinutes(now.minuteOfHour).setSeconds(0)
请注意,在 API 中,StartTimeOfDay 引用了 UTC(请参阅 API 参考:https://cloud.google.com/storage/transfer/reference/rest/v1/transferJobs#Schedule)。您通过电子邮件发送给我们的请求指定了基于 UTC 的过去一小时。请以 UTC 格式指定一天的开始时间。如果只想立即启动一次性作业运行,只需将"开始时间日期"字段留空即可。
另请注意,Google Cloud UI 允许客户以本地时区指定 StartTimeOfDay,这与 API 不同。
我发现存储传输服务很难开始工作。 有很多细微差别。清理文档并以清晰的方式在一个易于查找的地方获取所有信息将非常有帮助。
我之后的任何人的概述:
1) 创建服务帐户
2) 通过 IAM,为服务帐户赋予项目>编辑角色
3) 从 github.com/GoogleCloudPlatform/java-docs-samples/blob/master/storage/storage-transfer/src/main/java/com/google/cloud/storage/storagetransfer/samples/上的示例代码开始
-
3a) 只需要关注其中三个类:AwsRequester,TransferJobUtils & RetryHttpInitializerWrapper
3b) 创建一个存储传输客户端,需要Google-API-Services-storageTransfer jar,以连接您的秘密杰伦文件
-
3c) 创建一个 TransferJob 对象来提交作业,这是您在此处设置项目ID和计划,至少需要设置的位置日期,并将时间留为空以便立即提交,但您这样做需要创建时间表
3d) 创建一个 TransferSpec 对象,该对象将包含您的大部分配置选项。选项的映射尚不清楚。你需要使用 JSON API 文档,https://cloud.google.com/storage/transfer/reference/rest/v1/TransferSpec,并匹配 Java API 中的名称。至少,您需要
填充:AWS 存储桶和凭证、GCS 接收器等... 样品给你这个。 但您还需要设置ObjectConditions.setInclude带有字符串列表的前缀,相同通过用户界面的方式。
4)甚至不要费心去理解主页,cloud.google.com/storage/transfer/create-client,只读一次。它只是对真正使其工作没有帮助。
咦?