【问题标题】:Springboot, Micrometer and Aws Lambda functionSpring Boot、Micrometer 和 Aws Lambda 函数
【发布时间】:2021-08-21 21:39:56
【问题描述】:

我正在尝试使用千分尺将指标发送到 AWS cloudwatch,但是,我遇到了 AWS 凭证问题。

ERROR i.m.c.CloudWatchMeterRegistry - error sending metric data. 
com.amazonaws.SdkClientException: Unable to load AWS credentials from any provider in the chain: 
[com.amazonaws.auth.EC2ContainerCredentialsProviderWrapper@b23c49d: Failed to connect to service endpoint: , com.amazonaws.auth.profile.ProfileCredentialsProvider@7edf67de: profile file cannot be null]
    at com.amazonaws.auth.AWSCredentialsProviderChain.getCredentials(AWSCredentialsProviderChain.java:136)r 
    at com.amazonaws.http.AmazonHttpClient$RequestExecutor.getCredentialsFromContext(AmazonHttpClient.java:1257)r   
    at com.amazonaws.http.AmazonHttpClient$RequestExecutor.runBeforeRequestHandlers(AmazonHttpClient.java:833)r 
    at com.amazonaws.http.AmazonHttpClient$RequestExecutor.doExecute(AmazonHttpClient.java:783)r    
    at com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeWithTimer(AmazonHttpClient.java:770)r 
    at com.amazonaws.http.AmazonHttpClient$RequestExecutor.execute(AmazonHttpClient.java:744)r  
    at com.amazonaws.http.AmazonHttpClient$RequestExecutor.access$500(AmazonHttpClient.java:704)r   
    at com.amazonaws.http.AmazonHttpClient$RequestExecutionBuilderImpl.execute(AmazonHttpClient.java:686)r  at com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:550)r  
    at com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:530)r  at com.amazonaws.services.cloudwatch.AmazonCloudWatchClient.doInvoke(AmazonCloudWatchClient.java:2587)r 
    at com.amazonaws.services.cloudwatch.AmazonCloudWatchClient.invoke(AmazonCloudWatchClient.java:2554)r   
    at com.amazonaws.services.cloudwatch.AmazonCloudWatchClient.invoke(AmazonCloudWatchClient.java:2543)r   
    at com.amazonaws.services.cloudwatch.AmazonCloudWatchClient.executePutMetricData(AmazonCloudWatchClient.java:2297)r 
    at com.amazonaws.services.cloudwatch.AmazonCloudWatchAsyncClient$27.call(AmazonCloudWatchAsyncClient.java:1215)r    
    at com.amazonaws.services.cloudwatch.AmazonCloudWatchAsyncClient$27.call(AmazonCloudWatchAsyncClient.java:1209)r    
    at java.base/java.util.concurrent.FutureTask.run(Unknown Source)r   
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)r at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)r    
    at java.base/java.lang.Thread.run(Unknown Source)r

AmazonHttpClient 正在尝试使用 EC2ContainerCredentialsProviderWrapperProfileCredentialsProvider 检索凭证,但在 lambda 环境中,凭证可通过执行角色获得,而且我们有名为 AWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEY 的特定环境变量.

那么,有什么方法可以告诉 micrometer 使用不同的 AwsCredentials 提供程序,例如 EnvironmentVariableCredentialsProvider

【问题讨论】:

  • 您不能在提供CredentialProvider@Configuration 文件中创建@Bean 吗?
  • 您是如何创建CloudWatchMeterRegistry 的?自定义 CloudWatchAsyncClient 应该传递给它,然后它可以使用您想要的任何凭据提供程序。
  • @DejanPeretin 我不是自己创建的,它是作为 CloudWatchExportAutoConfiguration 中的 bean 提供的。您能否发布创建自定义 CloudWatchMeterRegistry 所需的答案?
  • @DejanPeretin 创建我的自定义 CloudWatchMeterRegistry bean 后,一切都开始工作了。我昨天试过了,但没有成功,因为 Terraform 没有更新我的 lambda 函数的代码。无论如何,它现在可以工作了,谢谢。

标签: spring-boot amazon-cloudwatch spring-boot-actuator micrometer spring-micrometer


【解决方案1】:

您是否尝试过使用Configuration 文件来为此更改Bean

@Configuration
public class ManualAWSCredentialProviderConfiguration {
  @Value("${AWS_ACCESS_KEY_ID}")
  protected String accessKey;

  @Value("${AWS_SECRET_ACCESS_KEY}")
  protected String secretKey;

  @Bean
  @Primary
  public AWSCredentialsProvider buildAWSCredentialsProviderManually() {
    return new AWSStaticCredentialsProvider(
      new BasicAWSCredentials(accessKey, secretKey)
    );
  }
}

【讨论】:

  • 不幸的是,它不起作用,同样的问题。
  • @ele 尝试记录 spring 分配给这些字符串的凭据
  • 问题是 Micrometer 仍在 Cloudwatch 客户端中使用 EC2 和 Profile 凭据提供程序。
【解决方案2】:

经过一些研究,我能够通过创建自定义 CloudWatchMeterRegistry bean 来发送指标,如下所示:

@Bean
@Primary
public CloudWatchMeterRegistry customCloudWatchMeterRegistry(
        CloudWatchConfig config, Clock clock, AwsRegionProperties awsRegionProperties) {

    AmazonCloudWatchAsync amazonCloudWatchAsync = AmazonCloudWatchAsyncClient
            .asyncBuilder()
            .withCredentials(new EnvironmentVariableCredentialsProvider())
            .withRegion(awsRegionProperties.getStatic())
            .build();

    return new CloudWatchMeterRegistry(config, clock, amazonCloudWatchAsync);
}

如您所见,现在我可以配置自定义凭据提供程序,在我的例子中是 EnvironmentVariableCredentialsProvider

重要提示: bean 的名称不应该是 cloudWatchMeterRegistry,因为此类 org.springframework.cloud.aws.autoconfigure.metrics.CloudWatchExportAutoConfiguration 已经声明了具有该名称的 bean。

【讨论】:

    【解决方案3】:

    当您将aws-java-sdk-sts 添加到您的依赖项(并且您将它放在您的类路径中)将导致扩展的提供程序链。然后应该使用执行角色。

    对于 Maven:

    <dependency>
        <groupId>com.amazonaws</groupId>
        <artifactId>aws-java-sdk-sts</artifactId>
        <version>1.12.52</version>
    </dependency>
    

    对于毕业:

    implementation group: 'com.amazonaws', name: 'aws-java-sdk-sts', version: '1.12.52'
    

    【讨论】:

      猜你喜欢
      • 2020-07-14
      • 2021-07-21
      • 1970-01-01
      • 2018-07-05
      • 2019-02-28
      • 1970-01-01
      • 1970-01-01
      • 2022-07-28
      • 1970-01-01
      相关资源
      最近更新 更多