【问题标题】:Aws How to know the region of the Bucket using Java SDKAws 如何使用 Java SDK 知道 Bucket 的区域
【发布时间】:2020-09-25 13:10:27
【问题描述】:

我使用以下代码获取listBuckets()

        AmazonS3ClientBuilder s3 = AmazonS3ClientBuilder.standard().withRegion("us-east-1");
        AmazonS3 s3Client = s3.build();
        bucketList = s3Client.listBuckets();

这里有两件事:

  1. 它返回所有存在的 Bucket 的列表,与区域无关。
  2. bucketList() 的每个项目是 Bucket 仅包含以下属性:
bucket.getName()
bucket.getOwner()
bucket.getCreationDate()

它不包含可以提供它所在区域的字段/方法

此外,当我尝试使用

获取此存储桶中 Objects 的计数时
s3Client.listObjectsV2(bucket.getName()).getKeyCount())

我得到以下异常:

com.amazonaws.services.s3.model.AmazonS3Exception: The bucket is in this region: us-east-2. Please use this region to retry the request (Service: Amazon S3; Status Code: 301; Error Code: PermanentRedirect;

我完全理解错误,但我需要以下所有方面的帮助:

  • 如何只为特定区域listBuckets(),而不为每个区域创建s3Client。假设我的s3Client 属于us-east-1,如何获取区域ap-south-1 中所有存储桶的列表。
  • 我如何知道listBucket() 响应中存在的每个存储桶的区域,因为只有name, owner, and creation date 属性。
  • 如何使用其他区域的 s3Client 获取其他区域的 Objects 列表。

我猜这和headers有关。

还有额外的帮助(否则我将不得不问另一个问题)

  • 在下载和上传对象时,如何显示对象的上传/下载进度,假设我的文件大小为 3GB,我需要一种方法来显示 50% 或一半填充的进度条可能显示 1.5 GB 已上传/下载。

【问题讨论】:

  • @mokugo-devops 大哥,再次需要你的帮助 :) .

标签: amazon-web-services amazon-s3


【解决方案1】:

无法将ListBuckets 的特定请求过滤到特定区域,因为该请求旨在列出您作为用户可用的所有存储桶。

但是,一旦您检索了 S3 存储桶,您就可以将每个存储桶的 Name 传递给从 S3Client 调用的函数 getBucketLocation

这样做会返回区域代码。

此过程的原因是 S3 存储桶被视为全球服务,每个存储桶名称都是唯一的,与区域无关。碰巧您选择了本地数据将存在的区域。

【讨论】:

  • 我如何从提供另一个区域的同一个 S3Client 调用 s3Client.listObjectsV2(bucket.getName()).getKeyCount())。或者创建另一个 S3Client/更改它的区域是唯一的选择?
  • 另外,您能否提供一些关于上述进度的奖励问题的提示?如果你建议,我也可以问另一个问题:)
  • 当我使用 getBucketLocation 时,它显示“授权标头格式错误;区域 'us-east-1' 错误;期待 'us-east-2'(服务:Amazon S3. .." 由于我无法提供正确的区域,我如何使用此功能获取区域信息?
【解决方案2】:

FWIW 我将添加到 Chris William 的正确答案中,即此方法可能不适用于跨账户存储桶访问。在这些情况下,在与其他账户上的存储桶不同的区域中创建 s3 客户端将导致尝试调用 headBucket 时出现重定向响应/错误,以及尝试调用 getBucketLocation 时出现错误。

我能找到查找存储桶区域甚至跨账户的唯一方法是调用headBucket 并使用重定向响应标头找出正确的区域,如下所示:

    S3Client s3 = S3Client.builder().build();
    HeadBucketRequest req = HeadBucketRequest.builder().bucket("aicore-segmenter").build();

    try {
        HeadBucketResponse res = s3.headBucket(req);
    } catch (S3Exception e) {
        if (e.statusCode() == 301) {
            String newRegionName = e.awsErrorDetails().sdkHttpResponse().headers().get("x-amz-bucket-region").get(0);
            Region newRegion = Region.of(newRegionName);
        }
    }

【讨论】:

    猜你喜欢
    • 2020-07-01
    • 2017-02-23
    • 2019-11-07
    • 1970-01-01
    • 2017-10-24
    • 2017-12-15
    • 2021-02-12
    • 2017-11-01
    • 1970-01-01
    相关资源
    最近更新 更多