消息发布者向RabbitMQ进行消息投递时默认情况下是不返回发布者该条消息在broker中的状态的,也就是说发布者不知道这条消息是否真的抵达RabbitMQ的broker之上,也因此会发生消息丢失的情况。

对此,RabbitmQ提供了两种解决方案(以官方提供的SDK为例)

1.通过AMOP提供的事务机制:

C#代码:

                try
{
channel.TxSelect();
channel.BasicPublish("yu.exchange", "yu.1", props, msg);
channel.TxCommit();
}
catch (Exception ex)
{
channel.TxRollback();
}

java代码是一样的操作。。。

        byte[] msg = "hello".getBytes();
try {
channel.txSelect();
channel.basicPublish("yu.exchange", "yu.1", MessageProperties.PERSISTENT_TEXT_PLAIN, msg);
channel.txCommit();
} catch (Exception ex) {
channel.txRollback();
}

事务开启,提交,回滚都有了。。。

2.Conform模式,也就是官网推荐的消息批量提交的方式

Conform模式主要包含两种编程模式,一种同步的,一种异步通知的:

同步回调的调用方式与事务模式差不多

C#代码:

                channel.ConfirmSelect();
byte[] msg = Encoding.UTF8.GetBytes("hello");
channel.BasicPublish("yu.exchange1", "yu.1", props, msg);
bool success = channel.WaitForConfirms(new TimeSpan(, , ));
Console.WriteLine(success);

Java代码:

        byte[] msg = "hello".getBytes();
channel.confirmSelect();
channel.basicPublish("yu.exchange", "yu.1", MessageProperties.PERSISTENT_TEXT_PLAIN, msg);
boolean success = channel.waitForConfirms();

通道Channel开启Conform,在发送完消息后可以通过WaitForConfirm等待消息的投递结果,这里有个可选参数,就是阻塞等待的时间,如果返回结果为false则表示消息投递失败,则发送端这时候也就可以采取重试之类的策略了。

异步回调的方式也就是通道订阅RabbitMQ的发送完毕确认事件,消息投递成功会回调这个方法给发送方,回调的参数包含当前消息在该通道中发送的编号DeliveryTag(批量提交的时候可以根据这个编号对应提交集合的索引,保证对应集合索引上的消息可靠投递),的最大值是9223372036854775807

C#代码:

           channel.BasicAcks += (sender, eventArgs) =>
{
ulong tag = eventArgs.DeliveryTag;
};
channel.BasicReturn += (sender, eventArgs) =>
{ };
byte[] msg = Encoding.UTF8.GetBytes("hello");
channel.BasicPublish("yu.exchange1", "yu.1", true, props, msg);

Java代码:

 channel.addConfirmListener(new ConfirmListener() {
public void handleAck(long l, boolean b) throws IOException {
System.out.println(l);
} public void handleNack(long l, boolean b) throws IOException {
System.out.println(l);
}
});
channel.addReturnListener(new ReturnListener() {
public void handleReturn(int i, String s, String s1, String s2, AMQP.BasicProperties basicProperties, byte[] bytes) throws IOException {
System.out.println("响应状态码-ReplyCode:"+i);
System.out.println("响应内容-ReplyText:"+s);
System.out.println("Exchange:"+s1);
System.out.println("RouteKey"+s2);
System.out.println("投递失败的消息:"+ new String(bytes,"UTF-8") );
            }
});
byte[] msg = "hello".getBytes();
channel.confirmSelect();
channel.basicPublish("yu.exchange1", "yu.1",true, MessageProperties.PERSISTENT_TEXT_PLAIN, msg);

代码中多订阅了一个BasicReturn事件(addReturnListener),当消息被RabbitMQ拒绝或者说没有成功投递的时候,则会触发这个方法,当然想要获取详细信息则需要设置mandatory参数为true,也就是basicPublish("yu.exchange1", "yu.1",true, MessageProperties.PERSISTENT_TEXT_PLAIN, msg);中的第三个参数。

队列中新建一个yu.exchange1的交换机然后不绑定队列的情况下则会投递失败的时间;

RabbitMQ如何保证发送端消息的可靠投递的更多相关文章

  1. RabbitMQ如何保证发送端消息的可靠投递-发生镜像队列发生故障转移时

    上一篇最后提到了mandatory这个参数,对于设置mandatory参数个人感觉还是很重要的,尤其在RabbitMQ镜像队列发生故障转移时. 模拟个测试环境如下: 首先在集群队列中增加两个镜像队列的 ...

  2. IM消息送达保证机制实现(二):保证离线消息的可靠投递

    1.前言 本文的上篇<IM消息送达保证机制实现(一):保证在线实时消息的可靠投递>中,我们讨论了在线实时消息的投递可以通过应用层的确认.发送方的超时重传.接收方的去重等手段来保证业务层面消 ...

  3. IM系统中如何保证消息的可靠投递(即QoS机制)(转)

    消息的可靠性,即消息的不丢失和不重复,是im系统中的一个难点.当初qq在技术上(当时叫oicq)因为以下两点原因才打败了icq:1)qq的消息投递可靠(消息不丢失,不重复)2)qq的垃圾消息少(它an ...

  4. RabbitMQ 消息的可靠投递

    mq 提供了两种方式确认消息的可靠投递 confirmCallback 确认模式 returnCallback 未投递到 queue 退回模式 在使用 RabbitMQ 的时候,作为消息发送方希望杜绝 ...

  5. IM系统中如何保证消息的可靠投递(即QoS机制)

      消息的可靠性,即消息的不丢失和不重复,是im系统中的一个难点.当初qq在技术上(当时叫oicq)因为以下两点原因才打败了icq:1)qq的消息投递可靠(消息不丢失,不重复)2)qq的垃圾消息少(它 ...

  6. springboot rabbitMQ 死信对列 实现消息的可靠消费

    1 引入 maven 依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifac ...

  7. 在服务端处理同步发送小消息的性能上Kafka>RocketMQ>RabbitMQ

    在发送小消息的场景中,三个消息中间件的表现区分明显: Kafka的吞吐量高达17.3w/s,远超其他两个产品.这主要取决于它的队列模式保证了写磁盘的过程是线性IO.此时broker磁盘IO已达瓶颈. ...

  8. 【RabbitMQ】如何进行消息可靠投递【上篇】

    说明 前几天,突然发生线上报警,钉钉连发了好几条消息,一看是RabbitMQ相关的消息,心头一紧,难道翻车了? [橙色报警] 应用[xxx]在[08-15 16:36:04]发生[错误日志异常],al ...

  9. 【RabbitMQ】如何进行消息可靠投递【下篇】

    说明 上一篇文章里,我们了解了如何保证消息被可靠投递到RabbitMQ的交换机中,但还有一些不完美的地方,试想一下,如果向RabbitMQ服务器发送一条消息,服务器确实也接收到了这条消息,于是给你返回 ...

随机推荐

  1. BZOJ3524: [Poi2014]Couriers(主席树)

    题意 题目链接 Sol 严格众数只会出现一次,那么建出主席树,维护子树siz,直接在树上二分即可 #include<bits/stdc++.h> #define LL long long ...

  2. Django中间件解析

    一,中间件的概念 django 中的中间件(middleware),在django中,中间件其实就是一个类,在请求到来和结束后,django会根据自己的规则在合适的时机执行中间件中相应的方法.在dja ...

  3. 记ASP.NET 使用 X509Certificate2 出现的一系列问题

    在做微信支付退款的时候,由于需要使用到p12证书,结果就遇到一系列的坑.这里做个记录方便以后查阅. 原先加载证书的代码: X509Certificate2 cert = new X509Certifi ...

  4. python之定义函数

    1.定义函数和参数检查 通过def语句定义一个函数,自己定义的函数,当参数个数不对时,python解释器可以抛出TypeError,但是当参数类型不对时,无法抛出TypeError,为此可以通过isi ...

  5. FFmpeg实现将图片转换为视频

    ##名称:ffmpeg实现将图片转换为视频 ##平台:ubuntu(已经安装好了ffmpeg工具) ##日期:2017年12月10日 简介: 因为学习需要,需要将连续图片转换成视频,昨天和今天早上用o ...

  6. Debian 8 升级到 9 Debian 9 How to upgrade Debian 8 Jessie to Debian 9 Stretch

    How to upgrade Debian 8 Jessie to Debian 9 Stretch Contents 1. Objective 2. What's New 3. Preparatio ...

  7. 可执行文件patch技术&&持续更新

    前言 在ctf比赛中, 有时我们需要对可执行文件进行patch, 或者在植入后门时,patch也是常用的手段.不过手工patch比较麻烦,下面介绍几个工具.本文介绍遇到的各种技术,不断更新. ELF ...

  8. Linux+db2+was部署问题总结

     Linux+db2+was部署问题总结 前段日子在住建部进行了Linux环境下,db2+rbp+was的部署,由于是集群,切涉及到了很多was的东西,搞了很长时间,在此做一个问题总结,供后续查询 ...

  9. statistical thinking in Python EDA

    Histgram直方图适合于单个变量的value分布图形 seaborn在matplotlib基础上做了更高层的抽象,方便对基础的图表绘制.也可以继续使用matplotlib直接绘图,但是调用seab ...

  10. SQL SERVER Management Studio编写SQL时没有智能提示的解决方式

    1. 检查设置里是否启用智能感知(Intellisence),可以在“工具”→“选项”里设置 2. 如果启用后还是无效,可以新建一个查询窗口查询,输入关键词的前面几个字母看是否有提示(或者使用Ctrl ...