0

このトピックに関する複数の回答を読みましたが、構成は適切に機能するはずですが、何らかの理由で機能しません。

構成は次のとおりです。

@Bean Queue intakeQueue(String name) { return new Queue(name, true); }

@Bean Exchange dlx(String name) { return new DirectExchange(name); }

@Bean Queue dlq(String name) { return new Queue(name, false, false, true); }

@Bean
Binding dlb(Exchange dlx, Queue dlq, Queue reply) {
    return BindingBuilder.bind(dlq).to(dlx).with(reply.getName()).noargs();
}

@Bean
Queue replyQueue(String name, Exchange dlx) {
    Map<String, Object> args = new HashMap<>();
    args.put("x-dead-letter-exchange", dlx.getName());
    args.put("x-dead-letter-routing-key", name);
    return new Queue(name, true, false, false, args);
}

RabbitMQ UI は、応答キューにDLXDLK属性があることを示しています。

みたいなメッセージを送ります

this.rabbit.convertSendAndReceive(intakeQueue, obj, message -> {
    message.getMessageProperties().setPriority(10);
    return message;
});

メッセージ ハンドラーAmqpRejectAndDontRequeueExceptionは、メッセージを受信した直後にスローします。これは、テストのみを目的として意図的に行われます。再試行のアドバイスから始めましたが、結果が得られなかったため、テスト ケースを単純化しました。

public Object handleMessage(Object obj) throws IOException {
    throw new AmqpRejectAndDontRequeueException("Testing retries!");
}

現在、次の 2 つの問題が発生しています。

  1. ARADRE がスローされた後、メッセージが DLQ に表示されません。でも直接DLQにパブリッシュすればOKhandleMessageです。
  2. convertSendAndReceive何も返されず(例外かもしれませんか?)、タイムアウトが発生するまで待機します。これは私の場合は5分です。意図したものかもしれませんが、RPC スタイルの呼び出しの場合はかなり奇妙です。

何かを見逃したり、設定を誤ったりしましたか?

4

1 に答える 1

1

その意味では RPC ではありません。リスナーで例外をスローしても、送信者には反映されません。

での配信を拒否すると、メッセージはそのDLX/DLQ (構成されている場合)intakeQueueにルーティングされます。

テスト ケースでは、応答キューの DLQ ではなく、そのDLQ (ある場合) を確認する必要があります。

RabbitMQ は、キューの関係を認識しません。コンテナーまたは構成は表示されませんRabbitTemplateが、既定では、直接の replyTo ルーティングが使用されます (「特別な」内部キューを使用します)。

固定応答キューを使用するようにウサギ テンプレートを構成できますが、その場合は、ドキュメント で説明されているように、応答リスナー コンテナーを提供する必要があります。

返信の受信時に送信者がタイムアウトした場合、テンプレートは をスローするARADREため、その場合、返信は配信不能になります。

それをテストするには、タイムアウトよりも長くリスナーでスリープしてから返信します。次に、返信が返信キューの DLQ に送られるのを確認する必要があります。

呼び出し元に例外を伝播したい場合は、それをhandleMessage戻り値として返す必要があります。

現在、そのような例外を再スローするロジックはありませんが、コードでそれを行う必要があります (応答が例外であることを検出して再スローします)。

もちろん、例外タイプは でなければなりませんSerializable

例外の伝播を処理するAMQPで Spring Remoting を使用することもできます。

于 2015-11-22T15:19:59.513 に答える