簡體   English   中英

AWS Java SDK - 無法通過區域提供商鏈找到區域

[英]AWS Java SDK - Unable to find a region via the region provider chain

我已經完成了標題為“以編程方式設置 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());
    }


}

}

問題 2:如果我想從中構建 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;
}

}

關於 Q1,嘗試使用以下語法構建您的客戶端:

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

正如上面的答案中提到的,您需要在同一區域擁有 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

更多詳細信息: 如何使用 AWS SDK 修復“無法通過區域提供商鏈找到區域”異常

PS:上面的鏈接轉到我的個人博客,其中包含有關此的其他詳細信息。

您可以采取以下步驟進行調查:

請確保您的 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 )

你可以試試這個

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

實際上,雖然我遇到了這個問題,但不可能一直更新代碼。

因此,我們需要調查發生這種情況的原因,在調查時我發現在您的根目錄下創建了.aws文件夾。 它的創建是因為我曾嘗試安裝aws console

解決方案是您需要使用區域更新您的配置文件。

這對我有用。

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

withRegion(Regions.DEFAULT_REGION)幫助我解決了我的問題

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

您可以在 AWS 環境中為您的 session 設置區域。

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

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

這對我行得通。

因此,問題的根本原因是AmazonS3需要知道要連接到的區域才能對 S3 存儲桶執行任何操作。

在我的情況下,不需要憑據,因為它是通過執行操作的服務器上的 IAM 角色處理的。

但是在注入我的 class 中定義的 bean 時, amazoneS3Client的初始化仍然失敗並出現錯誤

private final AmazonS3 amazonS3Client;

並且 spring 應用程序無法加載上下文,因為無法創建 bean。 AmazonS3 的 BeanCreation 失敗,根本原因如下

Failed to instantiate [com.amazonaws.services.s3.AmazonS3]: 
Factory method 'amazonS3Client' threw exception; nested exception is com.amazonaws.SdkClientException: 
Unable to find a region via the region provider chain. 
Must provide an explicit region in the builder or setup environment to supply a region.

因此,解決方法是在創建 bean 時配置區域。

@Bean
  AmazonS3 amazonS3Client() {
    return AmazonS3ClientBuilder.standard().withRegion(s3ConfigProperties.getRegion()).build();
  }

如您所見,我們在.withRegion() 中傳遞了區域,該區域在 application.yml 文件中定義。

 region: 'eu-west-1'

也可以通過aws configure CLI 命令為機器配置 AWS 區域

  • 鍵入aws configure命令。
  • 按 enter 不更改AWS Access Key IDAWS Secret Access Key
  • 當系統提示您添加區域時( Default region name [none]: ),鍵入ap-southeast-1 (或您需要的任何區域)並按回車鍵。

感謝@Matheus Sena在內部論壇上提出的建議

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM