Springboot、Micrometer 和 Aws Lambda 函数
Springboot, Micrometer and Aws Lambda function
我正在尝试使用千分尺将指标发送到 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.access0(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.call(AmazonCloudWatchAsyncClient.java:1215)r
at com.amazonaws.services.cloudwatch.AmazonCloudWatchAsyncClient.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 正在尝试使用 EC2ContainerCredentialsProviderWrapper
或 ProfileCredentialsProvider
检索凭据,但在 lambda 环境中,凭据可通过执行角色获得,而且我们还有特定的环境变量,称为 AWS_ACCESS_KEY_ID
和 AWS_SECRET_ACCESS_KEY
.
那么,有什么方法可以告诉 Micrometer 使用不同的 AwsCredentials 提供商,例如 EnvironmentVariableCredentialsProvider
?
您是否尝试过使用 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)
);
}
}
经过一些研究,我能够通过创建自定义 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
因为这个 class org.springframework.cloud.aws.autoconfigure.metrics.CloudWatchExportAutoConfiguration
已经有一个声明的 bean那个名字。
当您将 aws-java-sdk-sts
添加到您的依赖项(并将其放在您的类路径中)时,将导致扩展的提供者链。然后应该使用执行角色。
对于行家:
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-sts</artifactId>
<version>1.12.52</version>
</dependency>
对于gradle:
implementation group: 'com.amazonaws', name: 'aws-java-sdk-sts', version: '1.12.52'
我正在尝试使用千分尺将指标发送到 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.access0(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.call(AmazonCloudWatchAsyncClient.java:1215)r
at com.amazonaws.services.cloudwatch.AmazonCloudWatchAsyncClient.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 正在尝试使用 EC2ContainerCredentialsProviderWrapper
或 ProfileCredentialsProvider
检索凭据,但在 lambda 环境中,凭据可通过执行角色获得,而且我们还有特定的环境变量,称为 AWS_ACCESS_KEY_ID
和 AWS_SECRET_ACCESS_KEY
.
那么,有什么方法可以告诉 Micrometer 使用不同的 AwsCredentials 提供商,例如 EnvironmentVariableCredentialsProvider
?
您是否尝试过使用 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)
);
}
}
经过一些研究,我能够通过创建自定义 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
因为这个 class org.springframework.cloud.aws.autoconfigure.metrics.CloudWatchExportAutoConfiguration
已经有一个声明的 bean那个名字。
当您将 aws-java-sdk-sts
添加到您的依赖项(并将其放在您的类路径中)时,将导致扩展的提供者链。然后应该使用执行角色。
对于行家:
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-sts</artifactId>
<version>1.12.52</version>
</dependency>
对于gradle:
implementation group: 'com.amazonaws', name: 'aws-java-sdk-sts', version: '1.12.52'