AWS Java SDK - 无法通过区域提供商链找到区域

Posted

技术标签:

【中文标题】AWS Java SDK - 无法通过区域提供商链找到区域【英文标题】:AWS Java SDK - Unable to find a region via the region provider chain 【发布时间】:2017-10-24 10:05:16 【问题描述】:

我已经完成了题为“以编程方式设置 AWS 区域 1”的问题,但它并没有提供我需要的所有答案。

Q1:我收到了SDKClientException-Unable to find a region via the region provider chain。我究竟做错了什么?还是我漏掉了一个错字。

public class CreateS3Bucket 

public static void main(String[] args) throws IOException 

    BasicAWSCredentials creds = new BasicAWSCredentials("aws-access-key", "aws-secret-key");
    AmazonS3 s3Client = AmazonS3ClientBuilder.standard().withCredentials(new AWSStaticCredentialsProvider(creds)).build();

    Region region = Region.getRegion(Regions.US_EAST_1);
    s3Client.setRegion(region);

    try 
        String bucketName = "testBucket" + UUID.randomUUID();
        s3Client.createBucket(bucketName);
        System.out.println("Bucket Created Successfully.");

     catch(AmazonServiceException awse) 

        System.out.println("This means that your request made it AWS S3 but got rejected");
        System.out.println("Error Message:" +awse.getMessage());
        System.out.println("Error Message:" +awse.getErrorCode());
        System.out.println("Error Message:" +awse.getErrorType());
        System.out.println("Error Message:" +awse.getRequestId());

     catch (AmazonClientException ace) 

        System.out.println("The Amazon Client encountered an Error with network Connectivity");
        System.out.println("Error Message:" + ace.getMessage());
    



Q2:如果我想用它构建一个 Lambda 函数,需要做哪些代码更改?我知道如何创建它需要的 lambda 函数和角色。只需要知道我编写的代码是否需要更改。我应该如何实现 LambdaFuctionHandler 类如下:

import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;

 public class LambdaFunctionHandler implements RequestHandler<String, String> 

@Override
public String handleRequest(String input, Context context) 
    context.getLogger().log("Input: " + input);


    return null;



【问题讨论】:

【参考方案1】:

关于 Q1,尝试使用以下语法构建您的客户端:

AmazonS3 amazonS3 = AmazonS3Client.builder()
    .withRegion("us-east-1")
    .withCredentials(new AWSStaticCredentialsProvider(creds))
    .build();

【讨论】:

最好使用Regions.US_EAST_1 在您的应用中硬编码Region 几乎肯定是个坏主意。 在不了解问题的情况下寻求快速解决方案的人数是想要学习的人数的两倍。在发布评论时,这个不完整(因此不正确)的答案有 40 个赞,而由 Aniket Thakur 在下面发布的带有解释的正确答案有一半的赞(20)。【参考方案2】:

正如上面答案中提到的,您需要在同一区域拥有 S3 和 lambda,这就是为什么-

如果您没有使用withRegion 方法显式设置区域,SDK 会参考默认区域提供程序链来尝试确定要使用的区域。使用的方法之一是 -

已检查 AWS_REGION 环境变量。如果已设置,则该区域用于配置客户端。

对于 Lambda -

此环境变量由 Lambda 容器设置。

最后,要使用默认凭据/区域提供者链从环境中确定区域,请使用客户端构建器的 defaultClient 方法。

AmazonS3 s3Client = AmazonS3ClientBuilder.defaultClient();

这与使用标准后构建相同。

AmazonS3 s3Client = AmazonS3ClientBuilder.standard().build();

AWS 文档:https://docs.aws.amazon.com/sdk-for-java/v1/developer-guide/java-dg-region-selection.html

更多详情:How to fix "Unable to find a region via the region provider chain" exception with AWS SDK

PS:以上链接指向我的个人博客,其中包含更多详细信息。

【讨论】:

【参考方案3】:

实际上,当我遇到这个问题时,我不可能一直更新代码。

因此我们需要调查它发生的原因,在调查时我发现在您的根目录下创建了.aws 文件夹。之所以创建它是因为我前段时间尝试安装 aws console

解决方案是您需要使用区域更新配置文件。

【讨论】:

你拯救了我的一天。【参考方案4】:

您可以采取的调查步骤:

请确保您的 Lambda 函数和 S3 位于同一区域。 (当你使用 ProviderChain 时,它会从 Lambda 函数中获取区域

此外,如果您使用 Lambda,则不需要指定 BasicCredentials(aws-key..etc)。

请阅读 Lambda 权限模型 (http://docs.aws.amazon.com/lambda/latest/dg/intro-permission-model.html):

基本上,您分配的 Lambda 角色应该有权访问 S3。

你只需要配置 S3 就差不多了:

private static final AmazonS3 s3Client = 
AmazonS3ClientBuilder.defaultClient();

要在本地测试它,请确保您已在本地配置 AWS 凭证。

如果您进入 .aws/credentials(这将包含“aws-access-key”、“aws-secret-key”),您可以检查您是否拥有凭据

http://docs.aws.amazon.com/sdk-for-java/v1/developer-guide/setup-credentials.html

要在本地设置您的凭证,您只需运行 AWS Cli 命令:aws configure (http://docs.aws.amazon.com/cli/latest/userguide/cli-chap-getting-started.htm)

【讨论】:

【参考方案5】:

这对我有用。

AmazonS3 s3Client = AmazonS3ClientBuilder.standard().withCredentials(new ProfileCredentialsProvider()).withRegion(Regions.AP_SOUTH_1).build();

【讨论】:

【参考方案6】:

你可以试试这个

BasicAWSCredentials creds = new BasicAWSCredentials("your-accessKey", "your-secretKey");
AmazonSNS snsClient = AmazonSNSClientBuilder.standard()
        .withCredentials(new AWSStaticCredentialsProvider(creds))
        .withRegion(Regions.US_EAST_1).build();

【讨论】:

【参考方案7】:

withRegion(Regions.DEFAULT_REGION) 帮助我解决了我的问题

return AmazonS3ClientBuilder.standard()
.withCredentials(new AWSStaticCredentialsProvider(awsCredentials))
.withRegion(Regions.DEFAULT_REGION)
.build();

【讨论】:

【参考方案8】:

您可以在 AWS 环境中为您的会话设置区域。

如果您使用的是 Windows,请在 c:\user\%USERNAME%\.aws\config 中添加下一个文本:

[default]
region = us-east-1
output = json

这对我有用。

【讨论】:

以上是关于AWS Java SDK - 无法通过区域提供商链找到区域的主要内容,如果未能解决你的问题,请参考以下文章

即使在提供区域之后,aws-sdk v3 lambda 区域也缺失

DynamoDB跨区域复制AWS Java SDK

使用boto3 Python SDK返回AWS EC2可用性区域属性

Nodejs & aws-sdk:同时访问多个区域?

SparkApp 无法加载 Aws Java Sdk 定义

错误“Aws-sdk-java”与 maven 冲突