Apache Kafka Javaクライアント(0.9)を使用して、 Kafka Producerを使用して、ブローカーに長いレコードを送信しようとしています。クラス 。
非同期 send method はしばらくの間すぐに戻り、その後、各呼び出しで短時間ブロックを開始します。約30秒後、クライアントは例外( TimeoutException )をスローし始め、メッセージ "Batch expired"が表示されます。
どのような状況でこの例外がスローされますか?
この例外は、送信できるよりも速い速度でレコードをキューイングしていることを示します。
send メソッドを呼び出すと、ブローカーに送信するために ProducerRecord が内部バッファーに格納されます。メソッドは、送信されたかどうかに関係なく、 ProducerRecord がバッファリングされるとすぐに戻ります。
レコードは、ブローカーに送信するためにbatchにグループ化されます。これにより、メッセージごとの転送オーバーヒアを減らし、スループットを向上させます。
レコードがバッチに追加されると、指定された期間内に送信されるように、そのバッチを送信するための時間制限があります。これは、Producer構成パラメーター request.timeout.ms によって制御されます。デフォルトは30秒です。
バッチがタイムアウト制限よりも長くキューに入れられている場合、例外がスローされます。そのバッチ内のレコードは送信キューから削除されます。
構成パラメータを使用してタイムアウト制限を増やすと、クライアントは有効期限が切れる前により長い間バッチをキューに入れることができます。
私はこの例外をまったく異なるコンテキストで受け取りました。
Zookeeper vm、broker vm、およびproducer/consumer vmのミニクラスターをセットアップしました。サーバー(9092)とzookeeper(2181)で必要なポートをすべて開き、コンシューマー/パブリッシャーvmからブローカーにメッセージをパブリッシュしようとしました。私はOPで言及された例外を受け取りましたが、これまでに1つのメッセージしか公開していなかったので(または少なくとも試しました)、解決策はタイムアウトまたはバッチサイズを増やすことではありませんでした。そのため、コンシューマ/プロデューサーvm(ClosedChannelException)内からメッセージを消費しようとしたときに発生した同様の問題を説明するこのメーリングリストを検索しました。 http://grokbase.com/t/kafka/users/152jsjekrm/having-trouble-with-the-simplest-remote-kafka-config このメーリングリストの最後の投稿では、実際に問題を解決する方法について説明しています。
要するに、ChannelClosedException
とBatch Expired
の両方の例外に直面した場合、server.config
ファイルでこの行を次のように変更し、ブローカーを再起動する必要があります。
advertised.Host.name=<broker public IP address>
設定されていない場合は、Host.name
プロパティ(おそらくどちらも設定されていない)にフォールバックし、InetAddress
Javaの正規のホスト名にフォールバックします_クラスは、最終的にはもちろん正しくないため、リモートノードを混乱させます。
ブローカーに送信する前の時間を制御するパラメーターはlinger.ms
。デフォルト値は0(遅延なし)です。
私はKafka Javaクライアントバージョン0.11.0.0。一貫して大きなメッセージを生成するのに失敗して同じパターンを見始めました。メッセージ、および他のいくつかのために失敗します(成功したメッセージと失敗したメッセージは両方とも同じサイズでしたが)。私の場合、各メッセージサイズは約60KBで、Kafkaのデフォルトの_batch.size
_の16kBよりもはるかに大きく、 _linger.ms
_はデフォルトの0に設定されていました。サーバーからの正常な応答を受信する前にProducerクライアントがタイムアウトするため、このエラーがスローされます。基本的に、私のコードでは、この呼び出しはタイムアウトしました:kafkaProd.send(pr).get()
。これを修正するには、Producerクライアントのデフォルトの_request.timeout.ms
_を60000に増やす必要がありました
Kafka docker-composeで実行しています。docker-compose.ymlは次のように設定されています。
KAFKA_ADVERTISED_Host_NAME: kafka
ports:
- 9092:9092
しかし、外部のドッカーからラクダでメッセージを送信しようとしたとき
to("kafka:test?brokers=localhost:9092")
TimeoutExceptionが発生しました。追加して解決しました
127.0.0.1 kafka
windows\System32\drivers\etc\hostsファイルに移動し、ラクダのURLを
to("kafka:test?brokers=kafka:9092")