この記事は、変更を加えるための以前のブログ投稿springbootrabbitMQデッドレターキューに基づいています
メッセージ送信確認
送信されたメッセージはどのように失敗または成功としてカウントされますか?確認方法は?
RabbitTemplate.ReturnCallback
ReturnCallbackインターフェイスを実装することにより、メッセージがキューにルーティングされていないときにコールバックがトリガーされます。
RabbitTemplate.ConfirmCallback
ConfirmCallbackインターフェイスを実装することにより、メッセージがブローカーに送信された後にコールバックがトリガーされ、メッセージがブローカーサーバーに到達したかどうか、つまり、メッセージがExchangeに正しく到着したかどうかが確認されます。
コード例
プロデューサー
構成ファイルが変更されました
spring.rabbitmq.host=192.168.130.128
spring.rabbitmq.username=admin
spring.rabbitmq.password=admin
#开启消息确认机制
spring.rabbitmq.publisher-confirms=true
spring.rabbitmq.publisher-returns=true
#设置交换器名称
mq.config.exchange=direct_exchange
#设置队列的路由键
mq.config.queue.routing.key=test_key
ConfirmCallbackインターフェースを実装する
package com.sunyuqi.config;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.stereotype.Component;
@Component
public class MyConfirmCallback implements RabbitTemplate.ConfirmCallback {
@Override
public void confirm(CorrelationData correlationData, boolean ack, String cause) {
if (ack) {
System.out.println("消息发送到exchange成功,id: "+ correlationData.getId());
}
else {
System.out.println("消息发送到exchange失败,原因: "+cause);
}
}
}
ReturnCallbackインターフェイスを実装する
package com.sunyuqi.config;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.stereotype.Component;
@Component
public class MyReturnCallback implements RabbitTemplate.ReturnCallback {
@Override
public void returnedMessage(Message message, int replyCode, String replyText, String exchange, String routingKey) {
String correlationId = message.getMessageProperties().getMessageId();
String msg = new String(message.getBody());
System.out.println("[消息ID:"+correlationId+" ,内容:"+ msg+"]发送失败, 应答码:"+replyCode+" 原因:"+replyText+" 交换机: "+exchange+" 路由键: "+routingKey);
}
}
プロデューサークラス
package com.sunyuqi.routing;
import com.sunyuqi.config.MyConfirmCallback;
import com.sunyuqi.config.MyReturnCallback;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.util.UUID;
@Component
public class ProducerApp {
@Autowired
private RabbitTemplate rabbitTemplate;
//exChange 交换器
@Value("${mq.config.exchange}")
private String exChange;
//routingkey 路由键
@Value("${mq.config.queue.routing.key}")
private String routingKey;
/**
* 发送消息的方法
* @param msg
*/
@Autowired
private MyConfirmCallback myconfirmCallback;
@Autowired
private MyReturnCallback myReturnCallback;
public void send(Message msg){
//向消息队列发送消息
//参数1:交换器名称
//参数2:路由键
//参数3:消息
this.rabbitTemplate.setMandatory(true);
this.rabbitTemplate.setConfirmCallback(myconfirmCallback);
this.rabbitTemplate.setReturnCallback(myReturnCallback);
this.rabbitTemplate.convertAndSend(exChange,routingKey,msg,new CorrelationData(UUID.randomUUID().toString()));
}
}
テストクラス
package sunyuqi;
import com.alibaba.fastjson.JSON;
import com.sunyuqi.SpringbootdemoApplication;
import com.sunyuqi.entity.Student;
import com.sunyuqi.routing.ProducerApp;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageBuilder;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.UUID;
@RunWith(SpringRunner.class)
@SpringBootTest(classes = SpringbootdemoApplication.class)
public class QueueTest {
@Autowired
private ProducerApp producerApp;
@Test
public void test(){
Student student = new Student();
student.setId(1L);
student.setAge(18);
student.setName("jac");
student.setSex("男");
String s = JSON.toJSONString(student);
Message message = MessageBuilder.withBody(s.getBytes())
.setContentType(MessageProperties.CONTENT_TYPE_JSON)
.setContentEncoding("utf-8")
.setMessageId(UUID.randomUUID().toString()).build();
producerApp.send(message);
}
}
コンシューマーコードは変更されていません。コンシューマーブートクラスを開始し
てテストクラスを実行すると、メッセージが正常に送信され、成功メッセージが出力されます。
この時点でプロデューサー構成ファイルを変更します
#设置交换器名称
mq.config.exchange=direct_exchange1
テストクラスを再度実行しますが、スイッチが見つからない、つまりスイッチに正しく到達できません。
プロデューサー構成ファイルを再度変更してください。
#设置交换器名称
mq.config.exchange=direct_exchange
#设置队列的路由键
mq.config.queue.routing.key=test_key1
スイッチに正しく到達できますが、キューにルーティングできず、ReturnCallbackがトリガーされます