Java Kafka Streams在处理消息时发生异常时无法恢复
我正在玩卡夫卡溪,面临着一种对我来说似乎有点奇怪的情况。我对此进行了搜索,但没有找到正确的答案。 在处理流中的元素时,如果发生任何未经处理的异常,发生以下错误并且Kafka Streams无法恢复,则停止处理进一步的消息,然后我需要重新启动应用程序Java Kafka Streams在处理消息时发生异常时无法恢复,java,stream,apache-kafka,apache-kafka-streams,Java,Stream,Apache Kafka,Apache Kafka Streams,我正在玩卡夫卡溪,面临着一种对我来说似乎有点奇怪的情况。我对此进行了搜索,但没有找到正确的答案。 在处理流中的元素时,如果发生任何未经处理的异常,发生以下错误并且Kafka Streams无法恢复,则停止处理进一步的消息,然后我需要重新启动应用程序 2018-05-17 11:00:51.304 INFO 43810 --- [-StreamThread-3] o.a.k.s.p.internals.StreamThread : stream-thread [snapshot-
2018-05-17 11:00:51.304 INFO 43810 --- [-StreamThread-3] o.a.k.s.p.internals.StreamThread : stream-thread [snapshot-stream-application-a1dbc5d4-1742-4af2-9919-d4f5f861bb36-StreamThread-3] Stream thread shutdown complete
2018-05-17 11:00:51.304 WARN 43810 --- [-StreamThread-3] o.a.k.s.p.internals.StreamThread : stream-thread [snapshot-stream-application-a1dbc5d4-1742-4af2-9919-d4f5f861bb36-StreamThread-3] Unexpected state transition from RUNNING to DEAD.
2018-05-17 11:00:51.305 ERROR 43810 --- [-StreamThread-3] c.u.kafkastreams.config.SnapshotStream : Error while processing:
org.apache.kafka.streams.errors.ProcessorStateException: task [0_4] Failed to flush state store KTABLE-SOURCE-STATE-STORE-0000000000
当然,捕获所有异常将解决问题,但我正在为Kafka Streams寻找合适的异常处理机制。
以下是我的示例代码:
private KafkaStreams streams;
@PostConstruct
public void runStreams() {
KStreamBuilder builder = new KStreamBuilder();
KTable<String, String> snapshotTable = builder.table(kafkaProperties.getInputTopic());
snapshotTable.toStream().foreach((key, value) -> {
process(value);
});
streams = new KafkaStreams(builder, consumerProps());
streams.cleanUp();
streams.start();
streams.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
@Override
public void uncaughtException(Thread t, Throwable e) {
LOGGER.error("Error while processing:", e);
}
});
}
private void process(String message) {
simulateException(message);
LOGGER.info("Key: {} Value: {}", key, value);
}
private void simulateException(String message) {
if (message.contains("abc")) {
throw new RuntimeException();
}
}
@PreDestroy
private void closeStream() {
streams.close();
}
private Properties consumerProps() {
Properties config = new Properties();
config.put(StreamsConfig.APPLICATION_ID_CONFIG, "stream-application");
config.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, kafkaProperties.getBootstrap());
config.put(StreamsConfig.DEFAULT_KEY_SERDE_CLASS_CONFIG, Serdes.String().getClass());
config.put(StreamsConfig.DEFAULT_VALUE_SERDE_CLASS_CONFIG, Serdes.String().getClass());
config.put(StreamsConfig.COMMIT_INTERVAL_MS_CONFIG, 10000);
config.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest");
config.put(StreamsConfig.NUM_STREAM_THREADS_CONFIG, 3);
return config;
}
KafkaStreams私有流;
@施工后
公共void runStreams(){
KStreamBuilder builder=新的KStreamBuilder();
KTable snapshotTable=builder.table(kafkaProperties.getInputTopic());
snapshotTable.toStream().foreach((键,值)->{
过程(价值);
});
streams=新的KafkaStreams(生成器,ConsumerOps());
streams.cleanUp();
streams.start();
streams.setUncaughtExceptionHandler(新线程.UncaughtExceptionHandler(){
@凌驾
公共无效未捕获异常(线程t,可丢弃的e){
LOGGER.error(“处理时出错:”,e);
}
});
}
私有无效进程(字符串消息){
模拟异常(消息);
info(“Key:{}值:{}”,Key,Value);
}
私有void simulateException(字符串消息){
如果(消息包含(“abc”)){
抛出新的RuntimeException();
}
}
@发情前期
私有void closeStream(){
streams.close();
}
私有属性consumerProps(){
属性配置=新属性();
config.put(StreamsConfig.APPLICATION_ID_config,“流应用程序”);
config.put(ConsumerConfig.BOOTSTRAP_SERVERS_config,kafkaProperties.getBootstrap());
config.put(StreamsConfig.DEFAULT_KEY_SERDE_CLASS_config,Serdes.String().getClass());
config.put(StreamsConfig.DEFAULT_VALUE_SERDE_CLASS_config,Serdes.String().getClass());
config.put(StreamsConfig.COMMIT\u INTERVAL\u MS\u config,10000);
config.put(ConsumerConfig.AUTO_OFFSET_RESET_config,“最早”);
put(StreamsConfig.NUM\u STREAM\u THREADS\u config,3);
返回配置;
}
(我试过使用
kafka streams 0.11.0.0
和1.1.0
)您的代码不应该抛出异常。。。否则溪流就会死亡。那是故意的。捕捉所有异常是一种正确的设计。