我正在尝试使用 Kafka Streams (不是简单的Kafka使用者)从重试主题中读取以前无法处理的事件。我希望从重试主题开始使用,并且如果处理仍然失败(例如,如果外部系统出现故障),我希望将事件放回重试主题。因此,我不想立即消耗,而要在消耗之前稍等片刻,以免系统中出现暂时无法处理的消息。
简化后,代码当前正在执行此操作,我希望对此添加一个延迟。
fun createTopology(topic: String): Topology {
val streamsBuilder = StreamsBuilder()
streamsBuilder.stream<String, ArchivalData>(topic, Consumed.with(Serdes.String(), ArchivalDataSerde()))
.peek { key, msg -> logger.info("Received event for key $key : $msg") }
.map { key, msg -> enrich(msg) }
.foreach { key, enrichedMsg -> archive(enrichedMsg) }
return streamsBuilder.build()
}
我尝试使用“窗口延迟”进行此设置,但没有设法使其正常工作。我当然可以在peek
内入睡,但是那样会使线程挂起,而且听起来不是很干净的解决方案。
关于延迟如何工作的确切细节对于我的用例而言并不十分重要。例如,所有这些都可以正常工作:
x
秒内有关该主题的所有事件都被一次消耗掉。在开始消费/完成消费后,流将等待x
秒,然后再次消费x
秒被处理x
秒如果有人可以提供几行可以完成以上任何一项功能的Kotlin或Java代码,我将不胜感激。
答案 0 :(得分:0)
您不能真正使用Kafka Streams暂停从输入主题中读取内容,“延迟”的唯一方法是调用“睡眠”,但是正如您提到的那样,这阻塞了整个线程,不是一个好的解决方案。 / p>
但是,您可以做的是使用有状态处理器,例如process()
(带有附加状态存储)而不是foreach()
。如果重试失败,则不会将记录放回输入主题中,而是将其放到存储中,并且还要注册具有期望的重试延迟的标点符号。如果标点符号被触发,则重试;如果重试成功,则从存储中删除条目并取消标点符号;否则,您要等到标点再次触发。