web-dev-qa-db-ja.com

Kafkaストリームでの例外の処理

複数の投稿を通過しましたが、それらのほとんどは関連する処理です処理中の例外処理についてではなく、不良メッセージ。

ストリームアプリケーションが受信したメッセージの処理方法を知りたいのですが、メッセージの処理中に例外が発生しました。例外は、ネットワーク障害、RuntimeExceptionなどの複数の理由が原因である可能性があります。

  • 誰かが正しい方法は何かを提案できますか? setUncaughtExceptionHandlerを使用する必要がありますか?またはより良い方法はありますか?
  • 再試行の処理方法は?

前もって感謝します!!

10
Thiru

プロデューサー側の例外を除いて、何をしたいかによります。プロデューサーで例外がスローされる場合(たとえば、ネットワーク障害またはkafkaブローカーの停止))、ストリームはデフォルトで終了します。kafka-streamsバージョン1.1.0では、デフォルトの動作を上書きできます次のようにProductionExceptionHandlerを実装します。

public class CustomProductionExceptionHandler implements ProductionExceptionHandler {

    @Override
    public ProductionExceptionHandlerResponse handle(final ProducerRecord<byte[], byte[]> record,
                                                     final Exception exception) {
        log.error("Kafka message marked as processed although it failed. Message: [{}], destination topic: [{}]",  new String(record.value()), record.topic(), exception);
        return ProductionExceptionHandlerResponse.CONTINUE;
    }

    @Override
    public void configure(final Map<String, ?> configs) {
    }

}

handleメソッドから、例外でストリームを停止させたくない場合はCONTINUEを返し、ストリームを停止したい場合はFAILを返します(デフォルトはFAILです)。そして、あなたはストリーム設定でこのクラスを指定する必要があります:

default.production.exception.handler=com.example.CustomProductionExceptionHandler

また、ProductionExceptionHandlerはプロデューサーの例外のみを処理し、ストリームメソッドmapValues(..)filter(..)branch(..)などでメッセージを処理している間は例外を処理しないことに注意してください。これらのメソッドロジックをtry/catchブロックでラップする必要があります(すべてのメソッドロジックをtryブロックに入れて、例外的なケースをすべて処理できることを保証します)。

.filter((key, value) -> { try {..} catch (Exception e) {..} })

私が知っているように、kafkaストリームは後で自動的に再試行します(オフセットはメッセージが消費および処理されるまで変更されないため)ため、コンシューマ側で例外を明示的に処理する必要はありません);たとえば、kafkaブローカーがしばらくの間到達できない場合、kafkaストリームから例外が発生し、壊れるとアップしますkafkaストリームはすべてのメッセージを消費するため、この場合は遅延が発生し、破損したり失われたりすることはありません。

setUncaughtExceptionHandlerを使用すると、ProductionExceptionHandlerを使用した場合のようにデフォルトの動作を変更できなくなります。この場合、エラーをログに記録するか、失敗トピックにメッセージを送信することしかできません。

10

消費者側で例外を処理するために、

1)次のプロパティを使用して、プロデューサにデフォルトの例外ハンドラを追加できます。 "default.deserialization.exception.handler" = "org.Apache.kafka.streams.errors.LogAndContinueExceptionHandler";

基本的にApacheは3つの例外ハンドラークラスを提供します

1)props.put(StreamsConfig.DEFAULT_DESERIALIZATION_EXCEPTION_HANDLER_CLASS_CONFIG、LogAndContinueExceptionHandler.class);として取得できるLogAndContiuneExceptionHandler);

2)LogAndFailExceptionHandler props.put(StreamsConfig.DEFAULT_DESERIALIZATION_EXCEPTION_HANDLER_CLASS_CONFIG、LogAndFailExceptionHandler.class);

3)LogAndSkipOnInvalidTimestamp props.put(StreamsConfig.DEFAULT_DESERIALIZATION_EXCEPTION_HANDLER_CLASS_CONFIG、LogAndSkipOnInvalidTimestamp.class);

カスタム例外処理の場合、

1)DeserializationExceptionHandlerインターフェースを実装して、handle()メソッドをオーバーライドできます。

2)または、上記のクラスを拡張できます。

4
Vishal Pawar