rabbitmq保证消息丢失,这篇文章慢慢读完 应该可以懂

Rabbitmq
如果服务端需要发送消息给rabbitmq,有可能发送不到rabbimq(broker)中,这个时候,消息就可能会丢失,被了避免这种情况就需要将在application.perproties中配置1个属性 spring.rabbitmq.publisher-confirm-type=correlated 这个表示达到了还是没有到达rabbimtq(broker)中可以回调 public interface ConfirmCallback 这个接口中的方法,无论是到达了broker还是没有达到broker 都会回调这个接口 来看看方法的签名
//这个方法是RabbitTemplate中的方法 第一个参数 需要发送到的交换机,第2 个参数是发送到了队列,首先需要发送到交换机,然后通过交换机转发到信道,第三个参数就是消息体,第四个参数就是需要发送到唯一id号
void convertAndSend( String exchange, String routingKey, Object message, CorrelationData correlationData)
throws AmqpException;

correlationData 这个表示在发送方带来的唯一id前面,
ack 就是发送到rabbitmq是否到达broker 如果到达,就回返回true,
Cause,就是为什么不能到达rabbitmq 中到broker的原因
void confirm(@Nullable CorrelationData correlationData, boolean ack, @Nullable String cause);
这个方法无论是到达了broker还是没有发送到broker都会回调这个方法

如果我们达到了broker,交换机没有达到到队列,就回回调这个一下面的方法,并且你需要设置
spring.rabbitmq.publisher-returns=true //这个表示开启没有达到队列时需要会回调下面的方法
spring.rabbitmq.template.mandatory=true // 表示异步强制消息t

//message 消息体,就是发送方发送的消息体
// replcyCode 就是当没有达到队列时会返回你一个没有到达的原因code 就像HttpStatus.200一样
// replyTest 回复的文字
// exchange 就是发送方发送的交换机的名字
//routingKey 就是需要路由到那个队列的路由名字
void returnedMessage(Message message, int replyCode, String replyText, String exchange, String routingKey);

当我们发送方发送成功了,就需要我们回应一个应到信息,Ack,默认是自动ack
当在方法上定义了 @RabbitListener(queues = {“hello-java-queue”}) 或者是在类上面定义了@RabbitListener(queues = {“hello-java-queue”}) 并且在方法上面定义了@RabbitHandler 并且晓得完全晓得发送发送的什么消息,就可以在队列中拿到对应的消息体,看看下面的方法

// message 发送的消息,
// channel就是队列建立的通道,
// orderItemEntity我完全晓得发送发方发送来的对应的消息,它自动会帮我封装成这个对象
@RabbitHandler
public void rMessage(Message message, Channel channel,OrderItemEntity orderItemEntity) {

如果在默认的自动ack此时会有很多问题,当消费与rabibtmq建立一个长连接的时候,这个时候异步线程就会去rabbimq去把消息全部加载在java的缓存中,如果处理的消息正好处理到一半时宕机了 此时rabbimq中到消息全部丢失,这个就很严重了

为了避免这种消息就需要在配置文件中设置 spring.rabbitmq.listener.simple.acknowledge-mode=manual
手动ack ,此时手动ack需要在方法的前面中 调用channel.basicAck(deliverTag, multiple);

// 1. 第一个参数就是说当同一个channel中的deliverTag 这个参数的意思就是在当消息需要被方法指消费的时候就会被缓存,信道就会和缓存的消息被指定的方法调用,这个时候有好多个方法就是从0开始的 一直递增 可以从方法中的方法参数Message message 拿到deliveryTag ,message.getMessageProperties().getDeliveryTag()
// 2. 第二个参数就是是否需要批量处理,我们不需要,就false ,表示一个一个的处理消息 true 就是需要
void basicAck(long deliveryTag, boolean multiple) throws IOException;

// 需要注意的是,这个方法会抛出异常,就表示,有可能处理不成功,这个时候就需要捕捉到异常的时候,需要一个兜底的方法,
channel.basicNack(); 这个方法表示就是表示没有ack成功将消息是否返回给rabbimq 还是丢弃 看看下面的方法
// deliveryTag 就是从message拿到的tag
// 第二个参数就是如果失败了 是否需要批处理
// 第三个参数最关键 就是表示 是否将消息重新放回还是直接丢弃 需要注意的是,如果true就会将这个失败的方法重新放到队列,并且它的tag是从1开始的,表示排到最前面,如果是false 就表示直接丢弃 表示不管了
void basicNack(long deliveryTag, boolean multiple, boolean requeue)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值