发送时失败
properties spring.rabbitmq.publisher-confirm-type=correlated spring.rabbitmq.publisher-returns=true
消息发送给交换机后会触发confirm方法,无论有没有到达交换机
```java @GetMapping("push") public boolean push(){
User user = new User("医疗业务");
// 定义CorrelationData
CorrelationData correlationData = new CorrelationData();
correlationData.setReturnedMessage(new Message("自定义消息属性".getBytes(StandardCharsets.UTF_8), new MessageProperties()));
// 发送消息给message.log.test.exchange11交换机, 但实际rabbitmq并不存在, 会调用confirm()方法
template.convertAndSend("message.log.test.exchange11", "normalRouting",user,correlationData);
return true;
} ```
```java @Component public class ConfirmCallBack implements RabbitTemplate.ConfirmCallback {
@Resource
private RabbitTemplate rabbitTemplate;
@PostConstruct
public void init() {
rabbitTemplate.setConfirmCallback(this);
}
/**
* @param correlationData 消息属性体
* @param ack 是否成功, 成功到达true, 没有到达,false
* @param cause rabbitmq自身给的信息
*/
@Override
public void confirm(CorrelationData correlationData, boolean ack, String cause) {
if (!ack && correlationData == null) {
System.out.println(cause);
return;
}
if (!ack) {
Message message = correlationData.getReturnedMessage();
String messageBody = new String(message.getBody());
MessageProperties msgProperties = message.getMessageProperties();
//这里可以持久化业务消息体到数据库,然后定时去进行补偿处理或者重试
}
}
} ```
消息到达了rabbitmq的交换机,但没有到达队列,会触发return方法
```java @Component public class ReturnCallBack implements RabbitTemplate.ReturnCallback {
@Resource
private RabbitTemplate rabbitTemplate;
@PostConstruct
public void init() {
rabbitTemplate.setReturnCallback(this);
}
/**
* @param message 消息体
* @param replyCode 返回代码
* @param replyText 返回文本
* @param exchange 交换机
* @param routingKey 发送方定义的路由key
*/
@Override
public void returnedMessage(Message message, int replyCode, String replyText, String exchange, String routingKey) {
String messageBody = new String(message.getBody(), StandardCharsets.UTF_8);
System.out.println("消息标识:" + message.getMessageProperties().getDeliveryTag());
System.out.println("消息题:" + messageBody);
System.out.println(replyCode);
System.out.println(replyText);
System.out.println(exchange);
System.out.println(routingKey);
}
} ```
java @GetMapping("push2") public boolean push2(){ User user=new User(); user.setName("医疗业务"); template.convertAndSend("message.log.test2.exchange","message_loss_test",JSONObject.toJSON(user).toString()); return true; }
发送到消费端消费失败
开启消息手动确认,如果没有确认消息会重发
yaml rabbitmq: listener: simple: #开启手动确认 acknowledge-mode: manual #开启失败后的重试机制 retry: enabled: true #最多重试3次 max-attempts: 3
```java @Component @RabbitListener(queues = "myQueue") public class NormalConsumer { @RabbitHandler public void process(Map message, Channel channel, Message mqMsg) throws IOException { System.out.println("队列收到的消息为 : " + message.toString());
MessageProperties properties = mqMsg.getMessageProperties();
// 参数一:要确认的消息id
// 参数二:false表示只对当前的消息进行确认
channel.basicAck(mqMsg.getMessageProperties().getDeliveryTag(), false);
}
} ```
相关文章:
- https://juejin.cn/post/7146587225516408839
- https://juejin.cn/post/7117842051286171655#heading-3