繁体   English   中英

如何使用 spring webflux 从 Kafka 主题中持续消费?

[英]How to continually consume from Kafka topic using spring webflux?

我有一个名为WordListenerHandlerspring-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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM