Este artículo se basa en la publicación anterior del blog springboot rabbitMQ cola de mensajes no entregados para realizar cambios
Confirmación de envío de mensaje
¿Cómo se considera el mensaje enviado un error o un éxito? ¿Cómo confirmar?
RabbitTemplate.ReturnCallback
Al implementar la interfaz ReturnCallback, la devolución de llamada se activa cuando el mensaje no se enruta a la cola.
RabbitTemplate.ConfirmCallback
Al implementar la interfaz ConfirmCallback, se activa una devolución de llamada después de que el mensaje se envía al Broker para confirmar si el mensaje ha llegado al servidor del Broker, es decir, si ha llegado correctamente a Exchange.
Ejemplo de código
Productor
El archivo de configuración ha cambiado
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
Implementar la interfaz 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);
}
}
}
Implementar la interfaz 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);
}
}
Clase de productor
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()));
}
}
Clase de prueba
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);
}
}
El código del consumidor no se modifica, inicie la clase de arranque del consumidor y
ejecute la clase de prueba, el mensaje se envía correctamente y se imprime el mensaje de éxito.
Modifique el archivo de configuración del productor en este momento
#设置交换器名称
mq.config.exchange=direct_exchange1
Vuelva a ejecutar la clase de prueba, pero no se puede encontrar el conmutador, es decir, no se puede acceder al conmutador correctamente.
Modifique de nuevo el archivo de configuración del productor
#设置交换器名称
mq.config.exchange=direct_exchange
#设置队列的路由键
mq.config.queue.routing.key=test_key1
Puede alcanzar el conmutador correctamente, pero no se puede enrutar a la cola, lo que activa ReturnCallback