也许有人对我的下列问题有所了解:
我目前正在开展一个项目,我希望将AWS SQS与Spring Cloud集成使用。对于接收器部分,我想提供一个API,用户可以注册一个"消息处理程序"在队列上,这是一个接口,将包含用户的业务逻辑,例如
MyAwsSqsReceiver receiver = new MyAwsSqsReceiver();
receiver.register("a-queue-name", new MessageHandler(){
@Override
public void handle(String message){
//... business logic for the received message
}
});
我找到了例子,例如 https://codemason.me/2016/03/12/amazon-aws-sqs-with-spring-cloud/ 并阅读文件 http://cloud.spring.io/spring-cloud-aws/spring-cloud-aws.html#_sqs_support
但我唯一能找到的就是" connect"用于处理传入消息的功能是对方法的注释,例如, @SqsListener
或@MessageMapping
。
但是,这些注释固定为某个队列名称。所以现在我不知所措,如何动态地连接"我提供的" MessageHandler" (从我的API)到指定的queuename的传入消息。
在Config示例中有一个SimpleMessageListenerContainer
,它获得QueueMessageHandler
集,但是这个QueueMessageHandler看起来不像
是设置我的处理程序或覆盖其方法并提供我自己的QueueMessageHandler
子类的正确位置。
我已经使用Spring Amqp集成和RabbitMq做了类似的事情,并认为它与AWS SQS类似。
有没有人有想法,如何做到这一点?
thx + bye, Ximon
修改:
我发现,Spring JMS实际上可以做到这一点,例如 www.javacodegeeks.com/2016/02/aws-sqs-spring-jms-integration.html 。有谁知道,使用JMS协议有什么后果,好还是坏?
答案 0 :(得分:0)
当我们做Spring和SQS时,我们使用spring-cloud-starter-aws-messaging。
然后只创建一个Listener类
@Component
public class MyListener {
@SQSListener(value="myqueue")
public void listen(MyMessageType message) {
//process the message
}
}
答案 1 :(得分:0)
我面临同样的问题。
我试图以一种不寻常的方式在构建时设置一个 Aws 客户端 bean,然后我使用预定的注释,而不是使用 sqslistener 注释从特定队列中使用,我可以通过编程方式池< /strong>(在我的例子中每 10 秒)我想从哪个队列中消费。
我做了一个例子,遍历属性中定义的队列,然后从每个队列中消费。
客户端 Bean:
@Bean
@Primary
public AmazonSQSAsync awsSqsClient() {
return AmazonSQSAsyncClientBuilder
.standard()
.withRegion(Regions.EU_WEST_1.getName())
.build();
}
消费者:
// injected in the constructor
private final AmazonSQSAsync awsSqsClient;
@Scheduled(fixedDelay = 10000)
public void pool() {
properties.getSqsQueues()
.forEach(queue -> {
val receiveMessageRequest = new ReceiveMessageRequest(queue)
.withWaitTimeSeconds(10)
.withMaxNumberOfMessages(10);
// reading the messages
val result = awsSqsClient.receiveMessage(receiveMessageRequest);
val sqsMessages = result.getMessages();
log.info("Received Message on queue {}: message = {}", queue, sqsMessages.toString());
// deleting the messages
sqsMessages.forEach(message -> {
val deleteMessageRequest = new DeleteMessageRequest(queue, message.getReceiptHandle());
awsSqsClient.deleteMessage(deleteMessageRequest);
});
});
}
只是为了澄清,就我而言,我需要多个队列,每个租户一个,每个队列的队列 URL 都在属性文件中传递。当然,在您的情况下,您可以从另一个来源获取队列名称,也许是一个 ThreadLocal,其中包含您在运行时创建的队列。
如果您愿意,您还可以尝试使用 JMS 方法创建消息使用者并为您希望的每个使用者添加一个侦听器(请参阅文档 Aws Jms documentation)。