Java 如何基于来自sqs的消息创建流量?
我正在尝试创建一个SQS队列处理器,它处理来自SQS队列的消息,并 使用RSocket将它们流式传输到客户端 问题是我不知道怎么做,因为事先不知道消息列表 从我在网上读到的信息来看,我可能必须使用接收器来存储从队列接收到的消息,但我不知道如何干净地执行 (基于此) 如果有人能帮我,或者给我指出正确的方向,那就太好了 下面的代码可以工作。当消息被发送到队列时,它被Java 如何基于来自sqs的消息创建流量?,java,spring-boot,amazon-sqs,reactor,rsocket,Java,Spring Boot,Amazon Sqs,Reactor,Rsocket,我正在尝试创建一个SQS队列处理器,它处理来自SQS队列的消息,并 使用RSocket将它们流式传输到客户端 问题是我不知道怎么做,因为事先不知道消息列表 从我在网上读到的信息来看,我可能必须使用接收器来存储从队列接收到的消息,但我不知道如何干净地执行 (基于此) 如果有人能帮我,或者给我指出正确的方向,那就太好了 下面的代码可以工作。当消息被发送到队列时,它被receiveMessage方法读取,该方法将接收到的消息发送到接收器。如果客户端希望接收消息,则调用流方法,该方法在接收器上订阅。但我
receiveMessage
方法读取,该方法将接收到的消息发送到接收器。如果客户端希望接收消息,则调用流
方法,该方法在接收器上订阅。但我不明白的是,订阅部分log.info(“在流中接收{},消息)
中的代码不会被执行。但是如果我删除订阅部分,它就根本不起作用
private Many sink=Sinks.Many().multicast().directBestEffort();
私有AmazonSQSAsync AmazonSQSAsync;
@SqsListener(value=“${custom.sqs}”,deletionPolicy=SqsMessageDeletionPolicy.ON_SUCCESS)
公共无效接收消息(消息消息){
log.info(“收到来自sqs的消息:”+消息);
sink.emitNext(消息,Sinks.EmitFailureHandler.FAIL\u FAST);
}
@消息映射(“消息”)
通量流(最终整数延迟){
log.info(“收到的流请求,消息之间延迟{}秒”,延迟);
this.sink.asFlux().subscribe(消息->{
log.info(“在流中接收{}”,消息);
}).dispose()
返回这个.sink.asFlux();
}
根据Yuri的回答,下面的代码已经生成
private Many publisher=Sinks.Many().multicast().directBestEffort();
@SqsListener(value=“${custom.sqs}”,deletionPolicy=SqsMessageDeletionPolicy.ON_SUCCESS)
公共无效接收消息(消息消息){
log.info(“收到来自sqs的消息:”+消息);
this.publisher.emitNext(消息,Sinks.EmitFailureHandler.FAIL\u FAST);
}
@消息映射(“消息”)
通量流(最终整数延迟){
log.info(“收到的流请求,消息之间延迟{}秒”,延迟);
返回通量。创建(接收器->{
this.publisher.asFlux().subscribe(消息->{
sink.next(消息);
});
});
}
为了修复接收器发射异常,我使用了下面的代码,我从下面的
//来自:https://stackoverflow.com/questions/65029619/how-to-call-sinks-manyt-tryemitnext-from-multiple-threads/65185325#65185325
公共静态EmitFailureHandler retryOnNonSerializedElse(EmitFailureHandler回退){
返回(信号类型、发射结果)->{
if(emitResult==emitResult.FAIL\u非序列化){
锁支架。Parknos(10);
返回true;
}否则
返回fallback.onEmitFailure(信号类型,emitResult);
};
}
我在emitNext()
方法中使用了这个failureHandler,它是
在receiveMessages()
方法中调用
publisher.emitNext(消息,retryOnNonSerializedElse(Sinks.EmitFailureHandler.FAIL_FAST));
这是可行的,尽管我不完全理解为什么没有订阅,什么都不应该发生。Rx是一种固执己见的功能性方法,直到订阅建立一个操作链并在不启动它的情况下对其进行变异。删除订阅使其成为不可操作的。您可以使用类似链接帖子的处理器或在create lambda主体内使用Flux.create进行订阅。这还允许您处理取消和任何自然完成情况。查看您收到的每条消息都可以发送到sink。下一步()感谢您的回答!我选择使用Flux.create()因为当我使用
DirectProcessor
时,它给出了一个不推荐的
警告。最后的代码已经添加到了帖子中。我误解了,我认为很多代码来自SQS。我认为我给出了错误的建议。如果你已经有了流量,你可以希望完全从代码中删除订阅,并以返回这个。publish结束er.asFlux()
。当您返回通量时,框架应该为您调用subscribe,但我认为您说不是。这是因为sink.emitNext是同时调用的。请参阅: