Apache POIを使用してMicrosoft OfficeドキュメントからデータをプルするJavaコードをデバッグしています。時折、大きなドキュメントに遭遇し、メモリ不足になるとPOIがクラッシュします。その時点で、他のコンポーネントがこのステップが失敗したことを認識し、適切なアクションを実行できるように、エラーをRabbitMQに公開しようとします。ただし、キューにパブリッシュしようとすると、com.rabbitmq.client.AlreadyClosedException (clean connection shutdown; reason: Attempt to use closed channel)
を取得します。
エラーハンドラコードは次のとおりです。
try {
//Extraction and indexing code
}
catch(Throwable t) {
// Something went wrong! We'll publish the error and then move on with
// our lives
System.out.println("Error received when indexing message: ");
t.printStackTrace();
System.out.println();
String error = PrintExc.format(t);
message.put("error", error);
if(mime == null) {
mime = "application/vnd.unknown";
}
message.put("mime", mime);
publish("IndexFailure", "", MessageProperties.PERSISTENT_BASIC, message);
}
完全を期すために、公開方法は次のとおりです。
private void publish(String exch, String route,
AMQP.BasicProperties props, Map<String, Object> message) throws Exception{
chan.basicPublish(exch, route, props,
JSONValue.toJSONString(message).getBytes());
}
Tryブロック内でRabbitMQチャネルを閉じるように見えるコードが見つかりません。チャネルが暗黙的に閉じられる状況はありますか?
[〜#〜] edit [〜#〜]:publish内のbasicPublish
呼び出しによってAlreadyClosedExceptionがスローされることに注意してください。
AMQPチャネルは、チャネルエラーが発生すると閉じられます。チャネルエラーを引き起こす可能性のある2つの一般的なこと:
addShutdownListener() を使用してメッセージをパブリッシュするために使用しようとしているチャネルでShutdownListenerを設定して、シャットダウンイベントをキャッチし、その原因を調べます。
私の場合のもう1つの理由は、誤ってメッセージを2回確認したことです。これにより、2回目の確認後にログにRabbitMQエラーが発生します。
=ERROR REPORT==== 11-Dec-2012::09:48:29 ===
connection <0.6792.0>, channel 1 - error:
{amqp_error,precondition_failed,"unknown delivery tag 1",'basic.ack'}
重複した確認応答を削除すると、エラーがなくなり、チャネルが閉じなくなり、AlreadyClosedExceptionもなくなりました。
このトピックを検索する他のユーザーにこの情報を追加したい
チャネルクローズ例外を受信する別の考えられる理由は、パブリッシャーとコンシューマーが異なるキュー宣言/設定でチャネル/キューにアクセスしている場合です。
出版社
channel.queueDeclare("task_queue", durable, false, false, null);
ワーカー
channel.queueDeclare("task_queue", false, false, false, null);
RabbitMQサイトから
RabbitMQ doesn't allow you to redefine an existing queue with different parameters and will return an error to any program that tries to do that
消費チャネルが閉じている理由がわからない場合は、配信を2回以上確認するか、確認するかを確認してください。
Rabbitmqログには、次のようなメッセージが表示されます。
操作basic.ackにより、チャネル例外precondition_failedが発生しました:不明な配信タグ...
私もこの問題を抱えていました。私のケースの理由は、最初に永続= falseでキューを構築し、ログファイルに永続をtrueに切り替えたときにこのエラーメッセージがあったからです。
「vhost '/'のキュー 'logsQueue'の等価な引数 'durable': 'true'を受信しましたが、現在は 'false'です」
その後、キューの名前を変更しました。 RabbitMQサーバーは構築されたキューの記録をどこかに保持しており、ステータスを永続から非永続に、またはその逆に変更できないと想定しました。
繰り返しますが、私は新しいキューに対して耐久性=偽を作成しましたが、今回はこのエラーが発生しました
「vhost '/'のキュー 'logsQueue1'の等価な引数 'durable': 'false'を受信しましたが、currentは 'true'です」
私の仮定は真実でした。 rabbitMQサーバーのキューを次のようにリストしたとき:
rabbitmqctl list_queues
サーバーで両方のキューを見ました。
要約すると、2つの解決策は次のとおりです。1.良い解決策ではないキューの名前を変更する2.次の方法でrabbitMQをリセットする
rabbitmqctl stop_app
rabbitmqctl reset
rabbitmqctl start_app