1、RabbitMQ中的消息如何保障百分之百的投递成功?

  答:百分之百的投递成功,方案可以参考下面的2、3。

2、什么是生产者端的可靠性投递?

  答:第一步,生产者保障消息的成功发出。第二步,保障RabbitMQ的节点成功接收到生产者发送的消息。第三步,发送端收到RabbitMQ节点(即Broker)确认应答。第四步,完善的消息进行补偿机制。

3、如何实现生产端的可靠性投递,解决方案,如下所示。

  答:第一种,消息落库,对消息状态进行打标。意思是发送消息的时候,将消息持久化到数据库中,将消息设置一个状态,比如,刚发送出去,消息状态叫做发送中,当消息到达Broker端,Broker端返回给你一个响应,当你收到这个响应,代表了Broker端已经收到了该条消息(即应答确认),此时将消息的状态设置为发送成功,做一个打标。此时,针对没有进行响应的消息状态,可以做轮询操作,将未返回给你响应的消息进行重新发送(最大努力尝试值,可以手动设置)。直到所有消息发送成功并返回给你响应。

第二种,消息的延迟投递,做二次确认,回调检查。此种方式和减少和数据库的操作。第一种方式在高并发的场景下可能不是很适合。

4、RabbitMQ的幂等性概念。幂等性是什么,幂等性的概念。

  答:可能对一件事情进行一个操作,这个操作可能执行一百次或者一千次,最终执行结果都是相同的,即执行一百次或者一千次结果都是相同的。

5、消费端,幂等性保障,比如,在海量订单产生的业务高峰期,如何避免消息的重复消费问题?比如在高并发的情况下,会有好多消息到达RabbitMQ的Broker,消费端监听大量的消息,难免出现消息的重复投递,网络闪断导致的消息重复投递。如果不做消费端,幂等就会出现消息重复消费。

  答:消费端实现幂等性,就意味着,我们的消息永远不会消费多次,只能消费一次,即使我们收到了多条一样的消息。

6、主流的幂等性操作。

  方案一:唯一ID(全局生成的id) + 指纹码机制,利用数据库主键去重方案。好处是实现比较简单。坏处是高并发下有数据库写入的性能瓶颈。解决方案跟进ID进行分库分表进行算法路由。

  方案二:利用Redis的原子性去实现,实现去重,实现幂等性操作。需要考虑的问题,第一个问题是我们是否要进行数据落库,如果落库的话,关键解决的问题是数据库和缓存如何做到原子性。第二个问题,如果不进行落库,那么都存储到缓存中,如何设置定时同步的策略。

7、Confirm确认消息详解,理解Confirm消息确认机制。

  答:消息的确认,是指生产者投递消息后,如果Broker收到消息,则会给我们生产者一个应答。生产者进行接收应答,用来确定这条消息是否正常的发送到Broker,这种方式也是消息的可靠性投递的核心保障。

Confirm确认消息实现,如何实现Confirm确认消息?
  第一步,在channel上开启确认模式,即channel.confirmSelect()。调用方法进行确认模式的选择。
  第二部,在channel上添加监听,addConfirmListener,当broker回送应答的时候,根据addConfirmListener添加的监听进行接收broker回送的结果,根据回送的结果。监听成功和失败的返回结果,根据具体的结果对消息进行重新发送,或者记录日志等后续处理。

8、Return消息机制,Return Listener用于处理一些不可路由的消息。也是生产段添加的一个监听。

  我们的消息生产者,通过指定一个Exchange和Routingkey,把消息送达到某一个队列中去,然后我们的消费者监听队列,进行消息处理操作。但是在某些情况下,如果我们在发送消息的时候,当前的exchange不存在或者指定的路由key路由不到,这个时候如果我们需要监听这种不可达的消息,就要使用Return Listener。

  Return消息机制,在基础api中有一个关键的配置项。Mandatory,如果为true,则监听器会接收到路由不可达的消息,然后进行后续处理,如果为false,那么broker端自动删除该消息。

9、RabbitMQ消费端的限流策略,什么是消费端的限流。假设一个场景,首先,我们RabbitMQ服务器有上万条未处理的消息,我们随便打开一个消费者客户端,会出现下面的情况。巨量的消息瞬间全部推送过来,但是我们单个客户端无法同时处理这么多数据。

  1)、消费端限流,RabbitMQ提供了一种Qos(quality of service服务质量保证)功能,即在非自动确认消息的前提下,如果有一定数据的消息堆积,可以设置一个限制,我们不去更新消费,不去做ack,不去做确认机制。如果有一定数目的消息(通过基于consume或者channel设置Qos的值),消息未被确认前,不进行消费新的消息。Rabbitmq有两种签收模式,一种是自动签收,一种是手动签收。如果做消费端限流的话,不能设置自动签收模式,即autoack=false。

  2)、消费端的方法void BasicQos(unit prefetchSize,ushort prefetchCount,bool global);

    a、参数1是prefetchSize消息大小的限制,设置为0,不做大小限制。

    b、参数2是prefetchCount一次最多可以处理的消息,会告诉RabbitMQ不要同时给一个消费者推送多于N个消息,即一旦有N个消息还没有ack,则该consume将block掉,直到有消息ack。

    c、参数3是global是什么方式应用的,true表示channel的级别,false表示consume进行限制,true或者false是否将上面设置应用于channel简单点说,就是上面限制是channel级别的还是consumer级别。

  3)、注意:prefetchSize和global这两项,rabbitmq没有实现,暂且不研究prefetch_count在no_ask=false的情况下生效,即在自动应答(自动签收)的情况下这两个值是不生效的。

  4)、消费端的限流策略,开发步骤如下所示:

    第一步,限流方式,第一件事就是autoAck设置为false。
    第二步,channel.basicQos(0,1,false);
    第三步,手动确认,channel.basicAck(envelope.getDeliveryTag(),flase);参数1是deliveryTag,表示这一条消息已经处理完了,可以给一下条了,参数2是不批量签收,我们一条一条进行签收。

10、Rabbitmq的消费端ACK与重回队列。

  答:消费端可以进行手动的ACK和NACK。区分与ack自动确认签收,手动的ACK是代表消息确认了,消息已经收到了,确认了会给Broker端发送一个请求,说我已经收到了。手动NACK是代表了消息未进行确认,消息未收到或者处理失败了,Broker端将未收到的消息重新发送一遍。消费端进行消费的时候,如果由于业务异常我们可以进行日志的记录,然后进行补偿。如果由于服务器宕机等严重问题,那我们就需要手工进行ACK保障消费端消息成功。

  消费端的重回队列,消息未被处理成功,将该消息重新发送给Broker,消费端重回队列是为了对没有处理成功的消息,把消息重新会递给Broker。一般我们在实际应用中,都会关闭重回队列,也就是设置为False。

11、RabbitMQ的TTL队列或者消息,TTL是Time To Live的缩写,也就是生存时间。

  RabbitMQ支持消息的过期时间,在消息发送的时候可以进行指定。RabbitMQ支持队列的过期时间,从消息入队列开始计算,只要超过了队列的超时时间配置,那么消息会自动的清除。

12、死信队列,DLX,Dead-Letter-Exchange。

  1)、RabbitMQ的死信队列是路由到交换机上面的,RabbitMQ的死信队列是和Exchange、队列息息相关的。利用DLX,当消息在一个队列中变成死信(dead message,即这个消息没有任何消费者消费)之后,它能被重新publish到另一个Exchange,这个Exchange就是DLX(死信队列,Dead-Letter-Exchange)。
  2)、消息变成死信有以下几种情况。

    a、当消息被拒绝(basic.reject/basic.nack)并且requeue=false。
    b、消息TTL(TTL是Time To Live的缩写,也就是生存时间)过期。
    c、当队列达到了最大长度。

  3)、DLX也是一个正常的Exchange,和一般的Exchange没有区别,它能在任何的队列上被指定,实际上就是设置某个队列的属性。当这个队列中有死信的时候,RabbitMQ就会自动的将这个消息重新发布到设置的Exchange上去,进而被路由到另一个队列。可以监听这个队列中消息做相应的处理,这个特性可以弥补RabbitMQ3.0以前支持的immediate参数的功能。

  4)、死信队列设置,首先需要设置死信队列的exchange和queue,然后进行绑定。

    第一步、Exchange:dlx.exchange。死信队列就是一个正常的交换机Exchange。
    第二步、Queue:dlx.queue。需要将队列和这个交换机Exchange进行绑定。
    第三步、RoutingKey:#。任何的路由key都可以进行绑定。然后我们进行正常声明交换机,队列,绑定,只不过我们需要在队列加上一个参数即可:arguments.put("x-dead-letter-exchange","dlx.exchange");最后需要设置一个监听来监听这个队列。这样消息在过期、requeue、队列在达到最大长度的时候,消息就可以直接路由到死信队列了。

作者:别先生

博客园:https://www.cnblogs.com/biehongli/

如果您想及时得到个人撰写文章以及著作的消息推送,可以扫描上方二维码,关注个人公众号哦。

RabbitMQ的高级特性概念理解的更多相关文章

  1. Rabbitmq之高级特性——百分百投递消息&消息确认模式&消息返回模式实现

    rabbitmq的高级特性: 如何保障消息的百分之百成功? 要满足4个条件:生产方发送出去,消费方接受到消息,发送方接收到消费者的确认信息,完善的消费补偿机制 解决方案,1)消息落库,进行消息状态打标 ...

  2. rabbitmq系列(一)-基本概念理解

    1.简介 RabbitMQ是一个由erlang开发的AMQP(Advanced Message Queue protocol)的开源实现.AMQP高级消息队列,说白了就是一个开源的消息中间件.它能解决 ...

  3. Rabbitmq的高级特性

    消息如何保证100%投递成功? 什么是生产端的可靠性投递? 1.保障消息的成功发出 2.保障MQ节点的成功接收 3.发送端收到MQ节点(Broker)确认应答 4.完善的消息补偿机制 BAT互联网大厂 ...

  4. Rabbitmq之高级特性——实现消费端限流&NACK重回队列

    如果是高并发下,rabbitmq服务器上收到成千上万条消息,那么当打开消费端时,这些消息必定喷涌而来,导致消费端消费不过来甚至挂掉都有可能. 在非自动确认的模式下,可以采用限流模式,rabbitmq ...

  5. 消息中间件——RabbitMQ(七)高级特性全在这里!(上)

    前言 前面我们介绍了RabbitMQ的安装.各大消息中间件的对比.AMQP核心概念.管控台的使用.快速入门RabbitMQ.本章将介绍RabbitMQ的高级特性.分两篇(上/下)进行介绍. 消息如何保 ...

  6. 消息中间件——RabbitMQ(八)高级特性全在这里!(下)

    前言 上一篇消息中间件--RabbitMQ(七)高级特性全在这里!(上)中我们介绍了消息如何保障100%的投递成功?,幂等性概念详解,在海量订单产生的业务高峰期,如何避免消息的重复消费的问题?,Con ...

  7. RabbitMQ(二):RabbitMQ高级特性

    RabbitMQ是目前非常热门的一款消息中间件,不管是互联网大厂还是中小企业都在大量使用.作为一名合格的开发者,有必要了解一下相关知识,RabbitMQ(一)已经入门RabbitMQ,本文介绍Rabb ...

  8. 消息队列——RabbitMQ的基本使用及高级特性

    文章目录 一.引言 二.基本使用 1. 简单示例 2. work queue和公平消费消息 3. 交换机 三.高级特性 1. 消息过期 2. 死信队列 3. 延迟队列 4. 优先级队列 5. 流量控制 ...

  9. RabbitMQ实战(三)-高级特性

    0 相关源码 1 你将学到 如何保证消息百分百投递成功 幂等性 如何避免海量订单生成时消息的重复消费 Confirm确认消息.Return返回消息 自定义消费者 消息的ACK与重回队列 限流 TTL ...

随机推荐

  1. 955 不加班的公司名单:955.WLB

    前两天说到,韩老师的 Github 总 star 数量超过了 20000!全球排名第 232! 他,TypeScript GitHub Star 上海第一,全国第四!GitHub 总标星超两万! 其实 ...

  2. .NET Core 3终结点不能映射控制器

    今天在学.net core的时候发现了一个问题,终结点死活映射不了自己添加的控制器,后经过研究发现解决方法,可能这个问题不应该叫做问题,可是我是初学者,就把这个问题给拎出来.本人开发环境 VS2019 ...

  3. vue-practice

    vue-完整代码 这是一个完整的vue案例,但是接口似乎都失效了,单是代码本身还是很有参考价值的呦!~ 里面包含了:vue,vue-router,....,还是直接看json文件吧 { "n ...

  4. spring boot 2 + shiro 实现权限管理

    Shiro是一个功能强大且易于使用的Java安全框架,主要功能有身份验证.授权.加密和会话管理.看了网上一些文章,下面2篇文章写得不错.Springboot2.0 集成shiro权限管理 Spring ...

  5. PWM是如何调节直流电机转速的?电机正反转的原理又是怎样的?

    电机是重要的执行机构,可以将电转转化为机械能,从而驱动北控设备的转动或者移动,在我们的生活中应用非常广泛.例如,应用在电动工具.电动平衡车.电动园林工具.儿童玩具中.直流电机的实物图如下图所示. 1- ...

  6. 初识微信小程序

    一.简介 微信小程序是运行在微信环境中的应用,它只能在微信中运行,不能运行在浏览器等其他环境中,微信团队提供了专门的开发工具用于微信小程序的开发,还提供了丰富的API,让我们的小程序能够具备与手机设备 ...

  7. Dev 日志 | 如何将 jar 包发布到 Maven 中央仓库

    摘要 Maven 中央仓库并不支持直接上传 jar 包,因此需要将 jar 包发布到一些指定的第三方 Maven 仓库,比如:Sonatype OSSRH 仓库,然后该仓库再将 jar 包同步到 Ma ...

  8. WPF 后台模拟界面触摸点击

    win32Api提供一种方法,模拟用户触摸点击 InjectTouchInput function InitializeTouchInjection InjectTouchInput 在模拟添加触摸输 ...

  9. 简单了解一下:var 、let、const

    var 重新赋值,重新定义,作用域 属于:function scope: let 声明的变量只在 let 命令所在的代码块内有效,Block scope. const 声明一个只读的常量,一旦声明,常 ...

  10. SpringCloud服务配置中心

    SpringCloud Config简介 Spring Cloud Config 是 Spring Cloud 团队创建的一个全新项目,用来为分布式系统中的基础设施和微服务应用提供集中化的外部配置支持 ...