下面的代码重现了我在一些测试中看到的问题。我们
队列创建看似成功,并返回此 URL:
http://sqs.us-east-1.localhost:4566/000000000000/my-queue
但是,尝试查询队列属性会导致:
java.net.UnknownHostException: sqs.us-east-1.localhost
public class Main {
private static final LocalStackContainer localStack =
new LocalStackContainer(DockerImageName.parse(
"localstack/localstack:3.1")).withServices(SQS);
public static void main(String[] args) {
localStack.start();
// create SQS client
AmazonSQSAsync sqs = AmazonSQSAsyncClientBuilder
.standard()
.withEndpointConfiguration(new EndpointConfiguration(
localStack.getEndpointOverride(SQS).toString(),
localStack.getRegion()))
.withCredentials(new AWSStaticCredentialsProvider(
new BasicAWSCredentials(
localStack.getAccessKey(),
localStack.getSecretKey())))
.build();
// create a new queue
String url = sqs.createQueue("my-queue").getQueueUrl();
// get ARN of new queue
String arn = sqs.getQueueAttributes(url, List.of("QueueArn"))
.getAttributes().get("QueueArn");
}
}
上面的代码是 Maven 项目的一部分,具有这些(并且只有这些)依赖项:
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-sqs</artifactId>
<version>1.12.646</version>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>localstack</artifactId>
<version>1.19.4</version>
</dependency>
我不明白为什么
createQueue()
有效,但 getQueueAttributes()
不起作用。我在这里做错了什么?
[在“真实”代码中,我无法更改
aws-java-sdk-sqs
版本,但如果有帮助的话,我很乐意更改 TestContainers 和 LocalStack 版本]
更新:根据 Thrau 的建议修复(见下文)。需要使用最新的LocalStack并将
SQS_ENDPOINT_STRATEGY
设置为dynamic
:
LocalStackContainer localStack =
new LocalStackContainer(DockerImageName.parse("localstack/localstack:latest"))
.withEnv("SQS_ENDPOINT_STRATEGY", "dynamic")
.withServices(SQS);
一个简单的修复方法是使用
path
策略来生成 SQS 队列 URL,方法是添加
private static final LocalStackContainer localStack =
new LocalStackContainer(DockerImageName.parse("localstack/localstack:3.1"))
.withServices(SQS)
.withEnv("SQS_ENDPOINT_STRATEGY", "path");
说明:在LocalStack中,有不同的方式生成资源URL(例如SQS队列URL)。对于 SQS,它们记录在此处。
您的设置似乎使用了
standard
策略,其中队列 URL 模式为 sqs.<region>.localhost.localstack.cloud:4566/<account_id>/<queue_name>
。只是看起来您得到的不是 localhost.localstack.cloud
,而是 localhost
,这会导致无效的 URL。这可能是因为您还以某种方式将 LOCALSTACK_HOST
设置为 localhost
(也许这是测试容器的问题?)。使用 path
策略,即使您使用 localhost
作为默认本地堆栈主机名,您也将获得有效的 URL。