我目前在 AWS 有一个 spring boot 批处理作业(不要问我为什么 springboot 这不是我的决定!),即处理文件并通过 aws rds data api 对 rds postgres 执行插入和选择操作(也不是我的决定使用)。我正在使用适用于 java 版本 2.16.74 的 aws sdk 进行rds 数据 api 连接。该文件将包含大量记录,假设文件包含 700 条记录,则在处理文件时对数据 api 的调用会间歇性失败。文件中的每条记录都会创建 3 个数据 api 调用,有时其中一些调用会随机失败,并出现以下错误:
software.amazon.awssdk.core.exception.SdkClientException:无法从链 AwsCredentialsProviderChain(credentialsProviders=[SystemPropertyCredentialsProvider(),EnvironmentVariableCredentialsProvider(),WebIdentityTokenCredentialsProvider(),ProfileCredentialsProvider(),ContainerCredentialsProvider(),InstanceProfileCredentialsProvider 中的任何提供商加载凭据()]) : [SystemPropertyCredentialsProvider(): 无法从系统设置加载凭据。必须通过环境变量 (AWS_ACCESS_KEY_ID) 或系统属性 (aws.accessKeyId) 指定访问密钥。EnvironmentVariableCredentialsProvider():无法从系统设置中加载凭证。必须通过环境变量 (AWS_ACCESS_KEY_ID) 或系统属性 (aws.accessKeyId) 指定访问密钥。WebIdentityTokenCredentialsProvider():
代码 :
public RdsDataClient buildClient() throws AwsRdsDataException {
try {
RdsDataClient rdsData = (RdsDataClient)((RdsDataClientBuilder)RdsDataClient.builder().credentialsProvider((AwsCredentialsProvider)null)).build();
return rdsData;
} catch (SdkClientException var3) {
AwsRdsDataExceptionMessagesEnum exceptionMessage = AwsRdsDataExceptionMessagesEnum.RDS_DATA_API_CONNECTION_ISSUE;
throw new AwsRdsDataException(exceptionMessage.getErrorMessage(), var3.getCause(), exceptionMessage.getDescription(), 500);
}
}
public ExecuteStatementResponse executeStatement(String query) throws AwsRdsDataException {
LOG.info("Execute statement called with query: {} , param list: {}", query, this.dataQueryParamList);
RdsDataClient rdsData = this.buildClient();
try {
LOG.info("Rds Data Api Connector details resolved, Arn: {}, Secret: {}, Database:{}", new Object[]{this.resourceArn, this.secretArn, this.database});
ExecuteStatementRequest executeStatementRequest = (ExecuteStatementRequest)ExecuteStatementRequest.builder().resourceArn(this.resourceArn).secretArn(this.secretArn).database(this.database).sql(query).parameters(this.createSqlParameterList()).continueAfterTimeout(true).build();
return rdsData.executeStatement(executeStatementRequest);
} catch (StatementTimeoutException | InternalServerErrorException | ForbiddenException | ServiceUnavailableErrorException | BadRequestException var5) {
LOG.error("Execute statement failed: Error Message: {}, Cause: {}", var5.getMessage(), var5.getCause());
AwsRdsDataExceptionMessagesEnum exceptionMessage = AwsRdsDataExceptionMessagesEnum.INTERNAL_SERVICE_EXCEPTION;
throw new AwsRdsDataException(exceptionMessage.getErrorMessage(), var5.getCause(), exceptionMessage.getDescription(), exceptionMessage.getStatusCode());
}
}
任何人都知道此问题的根本原因,execute 语句因此错误而失败并抛出SdkClientException
.
Java 版本:java 11 aws coretto 版本。
Springboot:版本 2.2.0.RELEASE