我正在创建一个 Spring Boot 应用程序,以便将消息发布到在 Localstack 上运行的 AWS SQS 队列,以下是我的应用程序的关键文件:
docker-compose.yml文件
version: '3.7'
services:
aws:
image: 'localstack/localstack'
container_name: 'localstack'
environment:
- SERVICES=sqs,sns,dynamodb
- DEFAULT_REGION=us-east-1
- AWS_DEFAULT_REGION=us-east-1
- DEBUG=1
- DATA_DIR=/tmp/localstack/data
ports:
- '4566:4566'
volumes:
- "${LOCALSTACK_VOLUME_DIR:-./volume}:/var/lib/localstack"
- "/var/run/docker.sock:/var/run/docker.sock"
- ./localstack_bootstrap:/docker-entrypoint-initaws.d/
networks:
- websocket-network
td-listener:
build:
context: .
dockerfile: Dockerfile
command: bash -c "create-queue.sh"
depends_on:
- aws
ports:
- "8090:8090"
networks:
- websocket-network
networks:
websocket-network:
SQS 的初始化脚本(sqs_boostrap.sh)
#!/usr/bin/env bash
set -euo pipefail
# enable debug
# set -x
echo "configuring sqs"
echo "==================="
LOCALSTACK_HOST=localhost
AWS_REGION=us-east-1
create_queue() {
local QUEUE_NAME_TO_CREATE=$1
awslocal --endpoint-url=http://${LOCALSTACK_HOST}:4566 sqs create-queue --queue-name ${QUEUE_NAME_TO_CREATE} --region ${AWS_REGION} --attributes VisibilityTimeout=30
}
create_queue "sample-queue"
Spring boot application.yml
server:
port: 8090
cloud:
aws:
stack:
auto: false
region:
static: us-east-1
credentials:
access-key: 12345
secret-key: 12345
end-point:
uri: http://localstack:4566
td:
sample:
sqs:
queue:
url: http://localstack:4566/000000000000/sample-queue
groupid: samples
logging:
level:
org.springframework.web: DEBUG
我的 java 类试图到达 SQS 队列:
import com.amazonaws.services.sqs.AmazonSQS;
import com.amazonaws.services.sqs.AmazonSQSAsync;
import com.amazonaws.services.sqs.model.ListQueuesResult;
import com.amazonaws.services.sqs.model.SendMessageRequest;
import com.amazonaws.services.sqs.model.SendMessageResult;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.annotation.PostConstruct;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import java.util.UUID;
@Slf4j
@Service
@RequiredArgsConstructor
public class QuoteMessageListener extends WebSocketConnectionHandler {
private final AmazonSQS amazonSQS;
private final ObjectMapper objectMapper;
private final AmazonSQSAsync amazonSQSAsync;
@Value("${td.sample.sqs.queue.url}")
private String queueUrl;
@Value("${td.sample.sqs.queue.groupid}")
private String groupId;
@Override
public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) throws Exception {
log.info("Receive quote message {}", message.getPayload());
SendMessageRequest request = null;
try {
request = new SendMessageRequest()
.withQueueUrl(queueUrl)
.withMessageBody(objectMapper.writeValueAsString(message))
.withMessageGroupId(groupId);
final SendMessageResult result = amazonSQS.sendMessage(request);
log.info("Event message has been published in SQS with ID: {}.", result.getMessageId());
} catch (JsonProcessingException jpe) {
log.error("JsonProcessingException e : {} and stacktrace : {}", jpe.getMessage(), jpe);
} catch (Exception ex) {
log.error("Exception occurred while pushing event to sqs : {} and stacktrace ; {}", ex.getMessage(), ex);
}
log.info("END");
}
}
我尝试了多次更改才能到达 SQS 队列,但总是收到以下错误:
Region of queue URL http://localstack:4566/000000000000/sample-queue is ambiguous, got region us-east-1 from request
localstack.request.aws : AWS sqs.SendMessage => 400 (AWS.SimpleQueueService.NonExistentQueue)
localstack.request.http : POST /000000000000/sample-queue => 400
Exception occurred while pushing event to sqs : The specified queue does not exist for this wsdl version. (Service: AmazonSQS; Status Code: 400; Error Code: AWS.SimpleQueueService.NonExistentQueue;
非常感谢您对上述问题的提示或评论。
我认为您应该将 application.yml 中的“http://localstack:4566”引用替换为“http://localhost:4566”才能正常工作。哦还有,我认为默认访问密钥和密码是本地/本地的。以防万一我会更换这些。