RabbitMQ学习(三):高级特性

news/2024/11/23 3:01:12/

文章目录

    • 1 生产端如何可靠地投递消息
      • 1.1 消息落库打标
      • 1.2 消息延迟投递,通过二次确认回调检查。
    • 2 生产者确认(Confirm消息确认机制)
    • 3 消息的幂等性保障
      • 3.1 唯一ID + 指纹码 机制
      • 3.2 利用Redis的原子性实现
    • 4 Return消息机制
    • 5 消息的分发与消费端限流
      • 5.1 消息的分发
      • 5.2 消费端的限流
    • 6 消息的TTL
    • 7 队列的TTL

1 生产端如何可靠地投递消息

1.1 消息落库打标

消息落库,操作消息的状态位,然后利用定时任务轮询发送失败的消息并重试,但是不适合高并发场景。

  • 第一步:生产者将消息写入数据库。
  • 第二步:生产者向MQ发送消息。
  • 第三步:生产者监听消息发送状态(confirm)。
  • 第四步:生产者更新消息的状态位。
  • 第五步:启动一个分布式定时任务轮询发送失败的消息,并重新发送。

1.2 消息延迟投递,通过二次确认回调检查。

  • 第一步:生产者将消息写入数据库。
  • 第二步:生产者第一次向MQ发送消息。
  • 第三步:生产者第二次延迟向MQ发送消息(另一个队列)。
  • 第四步:消费者消费并生成一条新的确认消息,发送往MQ。
  • 第五步:另一个异步服务监听消费者的确认消息。
  • 第六步:异步服务将消息写入数据库。
  • 第七步:异步服务在另一个队列中收到了生产者发送的延迟消息。然后查询数据库确认是否成功处理,如果数据库中没有记录,就向生产者发送一个重新发送请求,重新发送该消息。

2 生产者确认(Confirm消息确认机制)

生产者投递消息后,如果Broker收到消息,就会给生产者一个应答,生产者接收到应答后就可以确认这条消息已正常发送到MQ中。

3 消息的幂等性保障

3.1 唯一ID + 指纹码 机制

根据唯一ID + 指纹码去数据库中查询是否有对应的记录,如果有则不处理消息到的消息。
好处:简单易实现,坏处:频繁操作数据库,有性能瓶颈。
解决方案:利用ID进行分库分表策略,进行算法路由,分摊数据库压力。

3.2 利用Redis的原子性实现

这个实现很简单,但是需要考虑以下两个问题:

  • 如果数据落库的话,需要解决数据库和缓存之间的原子性问题。
  • 如果数据不落库,应该设置怎样的定时同步策略。

4 Return消息机制

ReturnListener用于监听一些不可路由的消息,比如exchange不存在或者制定的routingkey路由不到。
主要涉及的配置项为mandatory

  • 为true,则生产者可以通过ReturnListener监听到,然后进行后续的处理。
  • 为false,则直接丢弃消息。
    与此同时,如果交换机将消息路由到队列时,发现队列上没有任何消费者,也会根据参数immediate做处理,不过该参数已经废弃了。

5 消息的分发与消费端限流

5.1 消息的分发

队列是以轮询的方式将消息分发给消费者。比如现在有n个消费者,会将第m条消息分发给m % n个消费者。

5.2 消费端的限流

通过channel.basicQos(int prefetchSize, int prefetchCount, boolean global)方法实现:

  • prefetchSize用于限制消费者所能接收未确认消息的数量。一般默认为0,表示无限制。
  • prefetchCount用于限制信道上的消费者所能保持的最大未确认消息的数量。
  • global,默认为false,如果为true,则信道上所有的消费者都需要受到prefetchCount的限制,如果为false,则信道上新的消费者需要受到prefetchCount的限制。
    注意:
  • autoAck设置为false。
  • 对拉模式无效。

6 消息的TTL

TTL是Time to Live的缩写,也就是生存时间,单位毫秒。

  • 在channel.queueDeclare方法中加入x-message-ttl参数,可以设置队列级别的过期时间。
  • 在channel.basicPublish方法中加入expiration属性,可以设置消息级别的过期时间。
  • 如果二者一起时间,则以消息的TTL二者之间较小的那个数值为准。
  • 推荐设置队列级别的过期时间,因为队列级别的过期消息处理只需要定期从队列头部开始扫描即可,而消息级别的过期消息处理需要扫描整个队列,性能低。

7 队列的TTL

  • 通过channel.queueDeclare方法中的x-expires参数设置队列被删除前空闲的时间。单位毫秒。
  • 如果RabbitMQ重启,持久化的队列的过期时间会被重新计算。

http://www.ppmy.cn/news/768907.html

相关文章

Spring事务的一些总结

文章目录 1 Transactional 注解特性2 事务的属性3 事务的嵌套4 事务超时设置5 Transaction注解不回滚的可能原因6 事务的基本要素(ACID)7 事务的原理8 数据并发问题9 数据库隔离级别10 Spring隔离级别11 底层所使用的不同的持久化API或框架 1 Transactional 注解特性 可以在整…

计算机科学与技术万金油专业,盘点工学大类里的“万金油”专业

原标题:盘点工学大类里的“万金油”专业 教育部2012年最新修订的本科生专业名录中把专业重新进行了从学科门类到专业类和专业的划分,共计12大学科门类,分别是理、工、农、医 ,管、教、文、艺 经、史、法、哲.92大专业类&#xff0…

程序员的浪漫(使用python画图)比心心(待完善版)

本人给女朋友准备的小惊喜,如有需要可以取用。(代码内有注释可根据需要更改) #比心!! import turtle # turtle.bgpic(D:/python/bjtp/aa.jpg) turtle.speed(10)#画笔速度 turtle.setup(1800,700,70,70) turtle.color(b…

一行代码解决判断IE浏览器和提示升级问题

IE8及以下版本提示升级&#xff08;使用IE9和旧版IE支持 if IE 条件注释语句实现&#xff09; <!--[if lte IE 8]><script>alert("您正在使用的浏览器版本过低&#xff0c;为了您的最佳体验&#xff0c;请先升级浏览器。");window.location.href"h…

win7 ie11版本安装报此更新不适用于计算机问题

IE版本升级需要KB2729094、KB2731771、KB2533623、KB2670838、KB2786081五个补丁安装 五个补丁需要根据计算机决定并下载&#xff0c;如&#xff1a;32位选x86 64位选X64 补丁安装时如果也出现了此更新不适用于计算机问题&#xff0c;可以在dos&#xff08;管理员身份&#xf…

浏览器为低版本IE的时候的信息提示;旧版 Internet Explorer 升级提示页;旧版 Internet Explorer 淘汰行动

本部分内容来自&#xff1a;https://support.dmeng.net/ 旧版 Internet Explorer 升级提示页 旧版 Internet Explorer 淘汰行动 微软对旧版 Internet Explorer 的支持服务已终止的说明 X-UA-Compatibility Meta Tag and HTTP Response Header if IE 条件注释说明 360浏览…

IE低版本常见的兼容问题解决

当每次谈到解决低版本IE兼容问题时&#xff0c;不知道大家有没有一种头皮发麻的感觉(内心独白&#xff1a;谁tm发明的IE&#xff0c;我要s了他&#xff0c;开个玩笑&#xff09;. 下面我们就简单谈一谈低版本IE常见的兼容问题&#xff1a; 在我们解决浏览器的兼容问题时&…

h5前端IE浏览器低版本判断及升级提示

需求&#xff1a; 由于公司项目对于ie浏览器只支持ie10及以上版本&#xff0c;为了更好的用户体验及人性化提示&#xff0c;想在代码里判断下ie浏览器低版本加个提示。 解决方案&#xff1a; 先贴代码&#xff1a; <!--[if lte IE 9]><script>alert("您正…