Spring Cloud AWS SQS无法在本地连接到服务端点

时间:2019-12-29 08:50:03

标签: java amazon-web-services spring-boot spring-cloud amazon-sqs

我正在尝试在一个正在进行的项目中使用Spring Cloud的AWS SQS。目前,我只在我的开发机器上本地运行该应用程序。因此,我想要的是连接到AWS上的SQS,而不必将我的应用程序部署到EC2实例。

但是,似乎Spring Cloud的AWS软件包中使用的AWS开发工具包将尝试通过元数据进行身份验证,并希望解析169.254.169.254/latest/meta-data/instance-id。由于我仍在本地运行应用程序,因此无法解析端点,并引发错误:

2019-12-29 16:38:27.420  WARN 22462 --- [  restartedMain] com.amazonaws.util.EC2MetadataUtils      : Unable to retrieve the requested metadata (/latest/meta-data/instance-id). Failed to connect to service endpoint: 

com.amazonaws.SdkClientException: Failed to connect to service endpoint: 
    at com.amazonaws.internal.EC2ResourceFetcher.doReadResource(EC2ResourceFetcher.java:100) ~[aws-java-sdk-core-1.11.699.jar:na]
    at com.amazonaws.internal.EC2ResourceFetcher.doReadResource(EC2ResourceFetcher.java:70) ~[aws-java-sdk-core-1.11.699.jar:na]
    at com.amazonaws.internal.InstanceMetadataServiceResourceFetcher.readResource(InstanceMetadataServiceResourceFetcher.java:75) ~[aws-java-sdk-core-1.11.699.jar:na]
    at com.amazonaws.internal.EC2ResourceFetcher.readResource(EC2ResourceFetcher.java:62) ~[aws-java-sdk-core-1.11.699.jar:na]
    at com.amazonaws.util.EC2MetadataUtils.getItems(EC2MetadataUtils.java:400) ~[aws-java-sdk-core-1.11.699.jar:na]
    at com.amazonaws.util.EC2MetadataUtils.getData(EC2MetadataUtils.java:369) ~[aws-java-sdk-core-1.11.699.jar:na]
    at org.springframework.cloud.aws.context.support.env.AwsCloudEnvironmentCheckUtils.isRunningOnCloudEnvironment(AwsCloudEnvironmentCheckUtils.java:38) ~[spring-cloud-aws-context-2.2.1.RELEASE.jar:2.2.1.RELEASE]
    at org.springframework.cloud.aws.context.annotation.OnAwsCloudEnvironmentCondition.matches(OnAwsCloudEnvironmentCondition.java:37) ~[spring-cloud-aws-context-2.2.1.RELEASE.jar:2.2.1.RELEASE]
    at org.springframework.context.annotation.ConditionEvaluator.shouldSkip(ConditionEvaluator.java:108) ~[spring-context-5.2.2.RELEASE.jar:5.2.2.RELEASE]
    at org.springframework.context.annotation.ConfigurationClassParser.processConfigurationClass(ConfigurationClassParser.java:221) ~[spring-context-5.2.2.RELEASE.jar:5.2.2.RELEASE]
    at org.springframework.context.annotation.ConfigurationClassParser.processImports(ConfigurationClassParser.java:587) ~[spring-context-5.2.2.RELEASE.jar:5.2.2.RELEASE]
...

我尝试在我的bean中显式提供一个SQS端点,但是它仍然尝试连接到169.254.169.254,导致上述错误:

public AmazonSQSAsync sqsClient() {
   EndpointConfiguration endpointConfig = new AwsClientBuilder.EndpointConfiguration(
        "sqs.us-east-1.amazonaws.com",
        "us-east-1"
   );

   return AmazonSQSAsyncClientBuilder
                .standard()
                .withEndpointConfiguration(endpointConfig)
                .withCredentials(new AWSStaticCredentialsProvider(new DefaultAWSCredentialsProviderChain().getCredentials()))
                .build();
}

尽管我不确定这一点,但我怀疑该错误正在发生,因为我在开发机器上本地运行该应用程序,因此无法解析为端点。但是我也不是很确定,因为我正在使用AWS开发工具包在同一应用程序中运行其他AWS服务,并且没有此错误。

我的pom.xml中具有以下依赖关系,似乎拥有其中任何一个都会导致错误发生。也就是说,我什至不必创建bean来产生该错误。由于某些原因,添加这些依赖项将立即导致SDK尝试解析该端点,并因该错误而失败。

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-aws</artifactId>
            <version>2.2.1.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-aws-messaging</artifactId>
            <version>2.2.1.RELEASE</version>
        </dependency>

我该怎么办才能解决无法连接到服务端点的错误?

10 个答案:

答案 0 :(得分:2)

我在为 AWS SNS 运行 Spring Boot 项目时收到以下错误

i.InstanceMetadataServiceResourceFetcher : Fail to retrieve token
com.amazonaws.util.EC2MetadataUtils      : Unable to retrieve the requested metadata (/latest/dynamic/instance-identity/document). Failed to connect to service endpoint:


Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'stackResourceRegistryFactoryBean' defined in class path resource [org/springframework/cloud/aws/autoconfigure/context/ContextStackAutoConfiguration.class]: Unsatisfied dependency expressed through method 'stackResourceRegistryFactoryBean' parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'amazonCloudFormation' defined in class path resource [org/springframework/cloud/aws/autoconfigure/context/ContextStackAutoConfiguration.class]: Invocation of init method failed; nested exception is java.lang.IllegalStateException: There is no EC2 meta data available, because the application is not running in the EC2 environment. Region detection is only possible if the application is running on a EC2 instance

Error creating bean with name 'org.springframework.cloud.aws.core.env.ResourceIdResolver.BEAN_NAME': Invocation of init method failed; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'stackResourceRegistryFactoryBean' defined in class path resource [org/springframework/cloud/aws/autoconfigure/context/ContextStackAutoConfiguration.class]: Unsatisfied dependency expressed through method 'stackResourceRegistryFactoryBean' parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'amazonCloudFormation' defined in class path resource [org/springframework/cloud/aws/autoconfigure/context/ContextStackAutoConfiguration.class]: Invocation of init method failed; nested exception is java.lang.IllegalStateException: There is no EC2 meta data available, because the application is not running in the EC2 environment. Region detection is only possible if the application is running on a EC2 instance

应用的分辨率: 将以下代码片段添加到 SpringBootApplication 中,然后单击 IDE 中的运行按钮

@SpringBootApplication(exclude = {ContextInstanceDataAutoConfiguration.class, ContextStackAutoConfiguration.class, ContextRegionProviderAutoConfiguration.class})

答案 1 :(得分:1)

在Spring Boot中运行s3存储桶时遇到了类似的错误,我使用创建存储桶时使用的位置解决了此问题:

   return AmazonS3ClientBuilder
            .standard()
            .withRegion("us-east-1")  //This is the code i added to fix 
            .withCredentials(new AWSStaticCredentialsProvider(awsCredentials))
            .build();

答案 2 :(得分:1)

我知道很多人已经解释了问题所在以及如何跳过此错误。但是,上述所有方法对我都不起作用。最后经过大量搜索,我设置了以下 aws 配置属性,它对我有用。

cloud.aws.region.use-default-aws-region-chain=true
cloud.aws.stack.auto=false
cloud.aws.credentials.access-key=
cloud.aws.credentials.secret-key=
cloud.aws.region.auto=false
cloud.aws.region.static=
cloud.aws.stack=false

logging.level.com.amazonaws.util.EC2MetadataUtils=error
logging.level.com.amazonaws.internal.InstanceMetadataServiceResourceFetcher=error

答案 3 :(得分:0)

据我了解,它试图从stacktrace

倒数第五个行检查您的应用程序是否在云环境上运行
  

org.springframework.cloud.aws.context.support.env.AwsCloudEnvironmentCheckUtils.isRunningOnCloudEnvironment(AwsCloudEnvironmentCheckUtils.java:38)

我签出了repo,这是代码段-

public static boolean isRunningOnCloudEnvironment() {
    if (isCloudEnvironment == null) {
        try {
            isCloudEnvironment = EC2MetadataUtils
                    .getData(EC2_METADATA_ROOT + "/instance-id", 1) != null;
        }
        catch (AmazonClientException e) {
            isCloudEnvironment = false;
        }
    }
    return isCloudEnvironment;
}

根据代码片段,它尝试获取实例metadata,如果失败则return false,这意味着您不在Cloud Environment上。但是,此代码有望捕获AmazonClientException,但您共享的 stacktrace 会抛出SdkClientException异常,这部分代码片段无法catch,因此可以不会返回false您不在云环境中。

此库版本似乎有些问题,根据堆栈跟踪,您正在使用2.2.1.RELEASE1,该版本仅在 9天发行了。您能否尝试使用其中一个较旧版本,然后报告是否仍然遇到相同的问题。


或者作为临时解决方案,您可以尝试隧道到您的VPC's entry server。如果需要,可以使用sshuttle进行隧道传输。这样一来,大部分IP也可以从本地计算机访问。

答案 4 :(得分:0)

  1. 在Spring应用程序属性中(或通过环境变量等)将cloud.aws.region.auto属性设置为false
  2. 定义cloud.aws.region.static属性。

这将告诉Spring不要使用基于自动检测的EC2元数据。一些details

您可能需要类似地配置凭据,您可以在同一文档中找到相关信息。

答案 5 :(得分:0)

在EC2实例之外使用AWS Java SDK时,您可以使用System propertyEnvironment variable禁用从EC2元数据实例服务加载证书或区域。

  • 系统属性:com.amazonaws.sdk.disableEc2Metadata
  • 环境变量:AWS_EC2_METADATA_DISABLED

但是,您仍然会在应用程序启动时收到警告,它告诉您EC2元数据已通过配置禁用:“ EC2实例元数据服务已禁用”

2020-03-27 18:10:42.483  WARN 71123 --- [main] com.amazonaws.util.EC2MetadataUtils      : Unable to retrieve the requested metadata (/latest/meta-data/instance-id). EC2 Instance Metadata Service is disabled

com.amazonaws.AmazonClientException: EC2 Instance Metadata Service is disabled
    at com.amazonaws.internal.InstanceMetadataServiceResourceFetcher.readResource(InstanceMetadataServiceResourceFetcher.java:65)
    at com.amazonaws.internal.EC2ResourceFetcher.readResource(EC2ResourceFetcher.java:66)
    at com.amazonaws.util.EC2MetadataUtils.getItems(EC2MetadataUtils.java:402)
    at com.amazonaws.util.EC2MetadataUtils.getData(EC2MetadataUtils.java:371)
    at org.springframework.cloud.aws.context.support.env.AwsCloudEnvironmentCheckUtils.isRunningOnCloudEnvironment(AwsCloudEnvironmentCheckUtils.java:38)
    ...

答案 6 :(得分:0)

问题在于弹簧云版本Hoxton.SR8。用Finchley.SR1替换pom.xml中的spring-cloud版本。

答案 7 :(得分:0)

解决了在application.yaml文件中添加的问题:

logging:
  level:
    com:
      amazonaws:
        util:
          EC2MetadataUtils: error

答案 8 :(得分:0)

我也遇到过类似的错误,但不是来自 Spring Cloud。当我在 application.properties 中添加以下配置时,错误消失了。

logging.level.com.amazonaws.util.EC2MetadataUtils=错误 logging.level.com.amazonaws.internal.InstanceMetadataServiceResourceFetcher=error

但是我在打开 s3a 路径时还面临其他一些问题。然后我打印了异常的堆栈跟踪,然后我得到了以下错误

由:com.amazonaws.SdkClientException:无法从链中的任何提供商加载 AWS 凭证:[BasicAWSCredentialsProvider:访问密钥或秘密密钥为空,WebIdentityTokenCredentialsProvider:您必须为 roleArn 指定一个值和 roleSessionName、EnvironmentVariableCredentialsProvider:无法从环境变量(AWS_ACCESS_KEY_ID(或 AWS_ACCESS_KEY)和 AWS_SECRET_KEY(或 AWS_SECRET_ACCESS_KEY))加载 AWS 凭证,com.amazonaws.auth.InstanceProfileCredentialsProvider@7700439a:无法连接到服务端点: /em>

凭证已经在 /.aws 文件夹中,但不确定为什么应用程序仍然给出错误。通过创建环境变量 AWS_ACCESS_KEY_ID、AWS_SECRET_KEY 和 AWS_SESSION_TOKEN 修复

答案 9 :(得分:0)

以下配置对我有用:

cloud:
  aws:
    region:
      auto: false
      static: eu-west-1
      use-default-aws-region-chain: true
    stack: false
    stack.auto: false
logging:
  level:
    com:
      amazonaws:
        internal:
          InstanceMetadataServiceResourceFetcher: error
        util:
          EC2MetadataUtils: error