rabbitmq消息防丢失

该文详细介绍了在Spring框架中使用RabbitMQ时,如何配置和实现消息发送的确认(confirm)和返回(return)回调,以及如何设置手动确认模式和消息重试策略。当消息无法送达交换机或队列时,系统会触发回调函数进行相应处理,如持久化消息到数据库以备补偿或重试。
摘要由CSDN通过智能技术生成

1.png

发送时失败

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值