[英]Springboot, Micrometer and Aws Lambda function
I'm trying to send metrics to AWS cloudwatch by using micrometer, however, I'm facing a problem with the AWS credentials.我正在尝试使用千分尺将指标发送到 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
The AmazonHttpClient is trying to retrieve the credentials using either the EC2ContainerCredentialsProviderWrapper
or ProfileCredentialsProvider
, but in the lambda environment the credentials are available through an execution role and also we have specific environment variables called AWS_ACCESS_KEY_ID
and AWS_SECRET_ACCESS_KEY
. AmazonHttpClient 正在尝试使用
EC2ContainerCredentialsProviderWrapper
或ProfileCredentialsProvider
检索凭据,但在 lambda 环境中,凭据可通过执行角色获得,而且我们还有名为AWS_ACCESS_KEY_ID
和AWS_SECRET_ACCESS_KEY
的特定环境变量。
So, is there any ways to tell micrometer to use a different AwsCredentials provider, for example EnvironmentVariableCredentialsProvider
?那么,有什么方法可以告诉千分尺使用不同的 AwsCredentials 提供程序,例如
EnvironmentVariableCredentialsProvider
?
Have you tried using a Configuration
file to change the Bean
for that?您是否尝试过使用
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)
);
}
}
After some research, I was able to send the metrics by creating a custom CloudWatchMeterRegistry
bean as follow:经过一些研究,我能够通过创建自定义
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);
}
As you can see, now I can configure a custom Credentials Provider, in my case the EnvironmentVariableCredentialsProvider
.如您所见,现在我可以配置自定义凭证提供程序,在我的例子中是
EnvironmentVariableCredentialsProvider
。
Important hint: The name of the bean shouldn't be cloudWatchMeterRegistry
because this class org.springframework.cloud.aws.autoconfigure.metrics.CloudWatchExportAutoConfiguration
already has a declared bean with that name.重要提示: bean 的名称不应该是
cloudWatchMeterRegistry
,因为这个 class org.springframework.cloud.aws.autoconfigure.metrics.CloudWatchExportAutoConfiguration
已经有一个使用该名称声明的 bean。
When you add aws-java-sdk-sts
to your dependencies (and thous having it on your classpath) will result in an extended provider chain.当您将
aws-java-sdk-sts
添加到您的依赖项(并且将它放在您的类路径中)时,将导致扩展的提供程序链。 Then the execution role should get used.然后应该使用执行角色。
For maven:对于 maven:
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-sts</artifactId>
<version>1.12.52</version>
</dependency>
For gradle:对于 gradle:
implementation group: 'com.amazonaws', name: 'aws-java-sdk-sts', version: '1.12.52'
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.