我有一个使用 SQS 队列的 Spring Boot 项目。对于本地测试,我使用带有 LocalStack 的 Docker 容器。为了使我的项目和 LocalStack 之间的连接正常工作,我发现的唯一方法是直接在配置类中覆盖 SQS 端点,如下所示:
@Configuration
public class SQSClientConfig {
@Bean
public SqsMessageListenerContainerFactory<Object> defaultSqsListenerContainerFactory() {
return SqsMessageListenerContainerFactory
.builder()
.sqsAsyncClient(sqsAsyncClient())
.build();
}
@Bean
public SqsAsyncClient sqsAsyncClient() {
var credentials = EnvironmentVariableCredentialsProvider.create();
return SqsAsyncClient.builder()
.credentialsProvider(credentials)
.endpointOverride(URI.create("http://localhost:4566")) *HERE*
.region(DefaultAwsRegionProviderChain.builder()
.build().getRegion())
.build();
}
@Bean
public Listener listener() {
return new Listener();
}
}
但是,由于我的项目也在AWS上的容器中运行,所以我不想每次在AWS中部署它时都删除这一行。有没有办法使用环境变量来覆盖 SQS 端点?我尝试了许多环境变量和配置属性,但连接始终回退到默认 URL (sqs.us-east-2.amazonaws.com)。
任何有关如何解决此问题的建议将不胜感激!
我建议采用以下方法:
在您的配置文件中,例如
application.yml
,定义如下键值对
sqs_endpoint: ${SQS_ENDPOINT:}
在示例的文件中,将
SqsAsyncClient
的定义更改为以下内容:
@Bean
public SqsAsyncClient sqsAsyncClient(@Value("${sqs_endpoint}") String sqsEndpoint) {
var credentials = EnvironmentVariableCredentialsProvider.create();
var builder = SqsAsyncClient.builder();
var isSqsEndpointPassed = sqsEndpoint != null && !sqsEndpoint.trim().isEmpty();
if (isSqsEndpointPassed) {
builder.endpointOverride(URI.create(sqsEndpoint))
}
return builder
.credentialsProvider(credentials)
.region(DefaultAwsRegionProviderChain.builder()
.build().getRegion())
.build();
}
当您在本地运行应用程序时传递环境值
java -jar app.jar -DSQS_ENDPOINT=http://localhost:4566
另一种常见方法是拥有 2 个活动配置文件 - 默认配置文件和本地配置文件。
在
application.yml
中定义默认配置,在 application-local.yml
中定义本地配置。-Dspring.profiles.active=local