赞
踩
1、RabbitMQ用在什么地方,工作中怎么使用的?
RAbbitMQ主要应用于订单系统中,不至于因为库存或支付或物流系统出现问题,而导致整个流程的阻塞。
2、RabbitMQ的特点,用什么语言写的
RabbitMQ基于面向并发的语言Erlang开发,消息可靠性较好。也能有效的保证消息的有序性。因为Erlang的原因,集群搭建比较方便。支持多种协议,并且有各种语言的客户端,比较灵活。
3、RabbitMQ的工作模式
1、简单队列模式 不用显示声明交换机,只需声明一个队列 生产者指定队列名发送消息给mq,然后会有一个默认的交换机将消息转发给这个队列。 消费者负责监听这个队列,一有消息就会得到通知做出响应。 2、工作队列模式(Work queues) 和简单队列模式基本一样,不过有一点不同,该模式有多个消费者在监听队列。 rabbitmq会以轮询的方式将消息发给多个消费者确保一条消息只会被一个消费者消费 3、发布订阅模式(Publish/subscribe) 和上面2种模式默认提供交换机不同的是,该模式需要显示声明交换机, 然后可以创建多个队列和这个交换机进行绑定。 生产者发消息给mq时需要指定交换机,然后交换机将消息转发给与自己绑定的所有队列 消费者监听指定的队列获得消息。每个队列可以有多个消费者监听,同样也是以轮询的机制发给消费者。 4、Routing 模式 和发布订阅模式不同的是,队列绑定交换机时需要指定一个routingkey 那么生产者发送消息时不仅需要指定交换机还需要指定routingkey 这样的话交换机就会把消息转发给跟自己绑定并且routingkey相匹配的队列 5、Topic模式 和Routing模式唯一的不同就是可以设置带有通配符进行模糊匹配的routingkey 6、heard模式 和Routing模式的不同就是 取消了routing 使用键值对的方式作为routing
4、如何保证消息不被重复消费
1、消息重复消费产生的原因:
因为网络故障,导致生产者确认机制失败,生产者重发消息或MQ重新投递消息
2、解决思路:业务处理时,保证处理消息接口的幂等性。
能根据具体的业务或状态来确定的,在消费端通过业务判断是否执行过,例如新增订单,看看订单ID是否已经存在
对于无法通过业务判断的,我们可以为每一条消息设置全局唯一id,保存到数据库消息表。消息处理前对ID进行判断即可
5、MQ的并发问题
用mq来将耗时比较长或者耗费资源的请求排队,异步处理,减轻服务器压力增加稳定性。
如果是高并发的实时请求,采用集群、分布式、动静分离、数据库读写分离之类的。
6、阻塞队列有哪些?区别是什么
在 J.U.C (java.util.concurrent)包中
1、ArrayBlockingQueue:典型的有界队列,其内部是用数组存储元素的,利用 ReentrantLock 实现线程安全,使用 Condition 来阻塞和唤醒线程;
2、LinkedBlockingQueue:是一个内部用链表实现的 BlockingQueue。如果我们不指定它的初始容量,那么它容量默认就为整型的最大值 Integer.MAX_VALUE,所以 LinkedBlockingQueue 也被称作无界队列,代表它几乎没有界限。同样也利用 ReentrantLock 实现线程安全,使用 Condition 来阻塞和唤醒线程。无法设置 ReentrantLock 的公平非公平,默认是非公平。也可以设置固定大小
3、SynchronousQueue:容量为 0,没有一个地方来暂存元素,导致每次取数据都要先阻塞,直到有数据被放入;同理,每次放数据的时候也会阻塞,直到有消费者来取。由于每当需要传递的时候,这个队列会把元素直接从生产者传给消费者,在此期间并不需要做存储,所以如果运用得当,它的效率是很高的。
4、PriorityBlockingQueue:是一个支持优先级的无界阻塞队列,可以通过自定义类实现 compareTo() 方法来指定元素排序规则,或者初始化时通过构造器参数 Comparator 来指定排序规则。同时,插入队列的对象必须是可比较大小的,也就是 Comparable 的,否则会抛出 ClassCastException 异常。
5、DelayQueue:是无界队列,放入的元素必须实现 Delayed 接口,而 Delayed 接口又继承了 Comparable 接口,所以自然就拥有了比较和排序的能力。而且5、DelayQueue:是无界队列,放入的元素必须实现 Delayed 接口,而 Delayed 接口又继承了 Comparable 接口,所以自然就拥有了比较和排序的能力。而且具有“延迟”的功能,可以设置队列中的任务多久以后再执行。
7、RabbitMQ的作用
1、解耦合
2、流量削峰填谷
3、异步调用
4、延迟队列
8、MQ有几种
1、ActiveMQ:基于 JMS,最老的消息中间件,社区不活跃
2、RabbitMQ:基于 AMQP 协议,erlang 语言开发,稳定性好,并发能力强、消息延时低、高可用、管理界面丰富,并且最重要的是:社区非常活跃,出现BUG都能及时解决。
3、RocketMQ:基于 JMS,高吞吐量。阿里巴巴产品,社区不太活跃,文档也不够丰富。
4、Kafka:类似 MQ 的产品;分布式消息系统,高吞吐量。但是消息可靠性比较一般,而且消息不保证有序性。
9、RabbitMQ的缺陷
如果延迟消息过多,可能导致MQ的消息堆积过多
MQ消息无法删除,因此不能撤销延迟消息。
10、RabbitMQ两种主流方式:AMQP、JMS 区别
1、JMS 是定义了统一的接口,来对消息操作进行统一;
2、AMQP 是通过规定协议来统一数据交 互的格式 - JMS 限定了必须使用 Java 语言;
3、AMQP 只是协议,不规定实现方式,因此是跨语言的。 - JMS 规定了两种消息模式;而 AMQP 的消息模式更加丰富。
11、如何保证消息的幂等性
1、消费数据为了单纯的写入数据库,可以先根据主键查询数据是否已经存在,如果已经存在了就没必要插入了。或者直接插入也没问题,因为可以利用主键的唯一性来保证数据不会重复插入,重复插入只会报错,但不会出现脏数据。
2、消费数据只是为了缓存到redis当中,这种情况就是直接往redis中set value了,天然的幂等性。
3、针对复杂的业务情况,可以在生产消息的时候给每个消息加一个全局唯一ID,消费者消费消息时根据这个ID去redis当中查询之前是否消费过。如果没有消费过,就进行消费并将这个消息的ID写入到redis当中。如果已经消费过了,就无需再次消费了。
12、如何利用RabbitMQ实现延迟队列
RabbitMQ中有一个死信队列设定:我们可以给一个队列设置过期时间,或者发送消息时给消息设置过期时间。过期的消息称为死信,队列会把死信转发给提前设置的死信交换机,而与死信交换机绑定的队列就可以拿到这些消息。因为发送消息超过一定时间(过期)后,才会被队列拿到,这样就实现了延迟队列效果。
1、Rabbit如何保证消息不丢失?
针对MQ消息丢失的几种不同情况,采用不同的应对方案:
1、生产者发送消息时可能因为网络问题导致消息丢失:
利用RabbitMQ提供的publisher confirm机制。
生产者发送消息后,可以编写成功回调函数或失败超时回调函数
RabbitMQ接收消息成功并持久化会调用成功回调函数,通知消息的发送者
RabbitMQ接收消息时出现异常会调用失败回调函数,通知消息的发送者
消息超时未发送成功也会调用失败回调函数
2、MQ宕机导致丢失消息:
消息持久化,RabbitMQ会将消息持久化到磁盘,宕机重启可以恢复消息
镜像集群,主从备份,避免引宕机导致消息丢失
3、消费者丢失消息:避免引消费者异常或宕机导致消息丢失
消费者的确认机制,在处理消息结束后,手动Acknowledge回执给MQ
MQ未接受到Acknowledge会认为消费失败,消息会保留在MQ
rabbitmq中消息消费后自动删除,不会永久保留,无法实现消息回溯。
1、如何保证更改数据时数据的一致性?
采用 TCC 模式 (Try-Confirm-Cancel)
一个完整的TCC业务由一个主业务服务和若干个从业务服务组成,主业务服务发起并完成整个业务活动,TCC模式要求从服务提供三个接口:Try、Confirm、Cancel。
1、第一阶段:主业务服务分别调用所有从业务的try操作,并在活动管理器中登记所有从业务服务。当所有从业务服务的try操作都调用成功或者某个从业务服务的try操作失败,进入第二阶段。
2、第二阶段:活动管理器根据第一阶段的执行结果来执行confirm或cancel操作。如果第一阶段所有try操作都成功,则活动管理器调用所有从业务活动的confirm操作。否则调用所有从业务服务的cancel操作。
3、需要注意的是第二阶段confirm或cancel操作本身也是满足最终一致性的过程,在调用confirm或cancel的时候也可能因为某种原因(比如网络)导致调用失败,所以需要活动管理支持重试的能力,同时这也就要求confirm和cancel操作具有幂等性。
1、RabbitMQ怎么使消息有序消费?
1、将原来的一个queue拆分成多个queue,每个queue都有一个自己的consumer。该种方案的核心是生产者在投递消息的时候根据业务数据关键值(例如订单ID哈希值对订单队列数取模)来将需要保证先后顺序的同一类数据(同一个订单的数据) 发送到同一个queue当中;
2、一个queue就一个consumer,在consumer中维护多个内存队列,根据业务数据关键值(例如订单ID哈希值对内存队列数取模)将消息加入到不同的内存队列中,然后多个真正负责处理消息的线程去各自对应的内存队列当中获取消息进行消费。
1、MQ的消息如何持久化
第一步:创建队列的时候将其设置为持久化,可以保证RabbitMQ持久化队列中的元数据。
第二步:发送消息时将消息的 deliveryMode 设置为2,将消息设置为持久化。就是将消息持久化到磁盘中
持续更新中。。。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。