LocalStack+AWS SQS+Spring Boot发送消息时HTTP请求执行失败
问题原因分析
你遇到的UnknownHostException: sqs.us-east-1.localstack是因为硬编码的队列URL使用了无法被测试环境解析的域名。sqs.us-east-1.localstack这个域名既没有在本地DNS配置中指向LocalStack容器,也不是Testcontainers暴露给主机的可访问地址,导致客户端无法找到对应的服务器。
另外,你虽然正确配置了AmazonSQS客户端使用LocalStack的endpoint,但在发送消息时手动拼接了错误的队列URL,绕过了SDK自动生成正确URL的逻辑,才触发了这个问题。
解决方案
核心思路是不要手动拼接队列URL,而是通过AWS SDK提供的方法获取正确的队列地址,具体修改如下:
1. 移除硬编码的SqsURL常量
删除代码中硬编码的final String SqsURL = "http://sqs.us-east-1.localstack:4566/000000000000/";,改用SDK方法获取队列URL。
2. 修改createQueueTest测试方法
通过createQueue的返回结果获取真实的队列URL,而不是断言硬编码的地址:
@ParameterizedTest @ValueSource(strings = {"news", "trends"}) @Order(2) void createQueueTest(String queueName) { // 获取创建队列后的返回结果,从中提取真实URL CreateQueueResult createQueueResult = amazonSQSClient.createQueue(queueName); String actualQueueUrl = createQueueResult.getQueueUrl(); var queues = amazonSQSClient.listQueues().getQueueUrls(); assertTrue(queues.contains(actualQueueUrl)); }
3. 修改saveToQueue测试方法
通过getQueueUrl方法获取正确的队列URL,替代手动拼接:
@ParameterizedTest @MethodSource("saveToQueue") @Order(3) void saveToQueue(String queueName, String data) { // 通过SDK获取队列URL,而非硬编码拼接 String url = amazonSQSClient.getQueueUrl(queueName).getQueueUrl(); amazonSQSClient.sendMessage(url, data); var messages = amazonSQSClient.receiveMessage(url); assertEquals(data, messages.getMessages().getFirst().getBody()); }
可选优化:使用LocalStack的服务endpoint配置(针对SDK v1)
如果需要确保SDK完全适配LocalStack,可以在构建客户端时添加withPathStyleAccessEnabled(true),强制使用路径风格的URL(而非子域名风格),避免子域名解析问题:
static AmazonSQS amazonSQS(String accessKey, String secretKey, String region, String stackEndpoint) { var basicAWSCredentials = new BasicAWSCredentials(accessKey, secretKey); var endpointConfiguration = new AwsClientBuilder.EndpointConfiguration(stackEndpoint, region); var credentialsProvider = new AWSStaticCredentialsProvider(basicAWSCredentials); return AmazonSQSClientBuilder.standard() .withEndpointConfiguration(endpointConfiguration) .withCredentials(credentialsProvider) .withPathStyleAccessEnabled(true) // 新增:强制路径风格访问 .build(); }
为什么这样修改能解决问题
- AWS SDK会根据你配置的LocalStack endpoint自动生成正确的队列URL,格式类似
http://localhost:4566/000000000000/news(具体地址由Testcontainers动态分配),这个地址是主机可以直接访问的。 - 避免了手动拼接URL带来的域名解析错误,完全利用SDK的内置逻辑适配LocalStack环境。
内容的提问来源于stack exchange,提问作者Nazar Havronskyi
相关产品推荐
相关产品推荐

