[英]How to continually consume from Kafka topic using spring webflux?
我有一个名为WordListenerHandler
的spring-webflux
处理程序,我可以从浏览器请求 HTTP GET。 此请求是Long
的 stream 使用Flux
: .body(Flux.interval(Duration.ofSeconds(1)).log(), Long.class)
因此它会不断更新 HTML 而不刷新页面。 我想显示 kafka topi 的消息,而不是 Long 值的 stream 的消息。 所以我有消费者方法onMessage(ConsumerRecord<String, String> consumerRecord)
正在接收消息,我正在填充一个Queue<String> stringStream
。 我的想法是在带有Flux.fromStream
的 HTTP GET 方法上使用这个队列。 但是是 static,我必须刷新浏览器才能看到更新。 如何让 HTTP GET stream 不断获取数据?
@Component
public class WordListenerHandler {
private final String WORDS_STREAMING_OUTPUT_TOPIC_NAME = "streaming-words-output-topic";
Queue<String> stringStream = new LinkedList<String>();
public Mono<ServerResponse> fluxWordCountStream(ServerRequest serverRequest) {
return ServerResponse.ok()
.contentType(MediaType.APPLICATION_STREAM_JSON)
// DOES NOT WORK. i HAVE TO REFRESH THE BROWSER
.body(Flux.fromStream(stringStream.stream()), String.class);
// THIS WORKS AND I CAN CONTINUALLY SEE MY BROWSER UPDATE WITHOUT REFRESHING IT
// .body(Flux.interval(Duration.ofSeconds(1)).log(), Long.class);
}
@KafkaListener(topics = {WORDS_STREAMING_OUTPUT_TOPIC_NAME})
public void onMessage(ConsumerRecord<String, String> consumerRecord) throws JsonProcessingException {
log.info("ConsumerRecord received: {}", consumerRecord);
String message = consumerRecord.key() + " : " + consumerRecord.value() + "\n";
stringStream.add(message);
}
}
我建议查看Sink
Reactor 的 API: https://projectreactor.io/docs/core/release/reference/#sinks
因此,您的@KafkaListener
将以背压方式将接收到的数据转储到共享的Sinks.Many
中。
而您的MediaType.APPLICATION_STREAM_JSON
只会使用来自该接收器的asFlux()
。
我相信您的问题是该集合中的stringStream.stream()
不会提供实时 object,而是该集合的当前 state 的快照。 因此,您需要刷新请求以从集合中获取更新 state 确实看起来很自然。
尝试使用LinkedBlockingQueue
而不是LinkedList
(它不是线程安全的)。
* <p>The iterators returned by this class's {@code iterator} and
* {@code listIterator} methods are <i>fail-fast</i>: if the list is
* structurally modified at any time after the iterator is created, in
* any way except through the Iterator's own {@code remove} or
* {@code add} methods, the iterator will throw a {@link
* ConcurrentModificationException}. Thus, in the face of concurrent
* modification, the iterator fails quickly and cleanly, rather than
* risking arbitrary, non-deterministic behavior at an undetermined
* time in the future.
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.