MQ的了解:
如果进行产品选型
Kafka
优点:吞吐量非常大,性能非常好,集群高可用。
缺点:会丢数据,功能比较单一
使用场景:日志分析、大数据采集
RebbitMQ
优点:消息可靠性高,功能全面。
缺点:吞吐量比较低,消息积累会严重影响性能。erlang语言不好定制。
使用场景:小规模场景。
RocketMQ (阿里产品)
优点:高吞吐、高性能、高可用,功能非常全面。
缺点:开源版功能不如云上商业版。官方文档和周边生态还不够成熟。客户端只支持java
使用场景:几乎是全场景。
rabbitmq的镜像队列原理(需要集群)
如何保证消息的顺序?
全局有序和局部有序:MQ只需要保证局部有序,不需要保证全局有序。
生产者把一组有序的消息放到同一个队列当中,而消费者一次消费整个队列当中的消息。
RocketMQ中有完整的设计,但是在RabbitMQ和Kafka当中,并没有完整的设计,需要自己进行设计。
RabbitMQ:要保证目标exchange只对应一个队列。并且一个队列只对应一个消费者。
Kafka:生产者通过定制partition分配规则,将消息分配到同—个partition。Topic下只对应一个消费者。
rabbitmq的死信队列、延迟队列原理
延迟队列可以说是死信交换机+ttl
死信消息:
1.消息被消费方否定确认,使用 channel.basicNack 或 channel.basicReject,并且此时 requeue 属性被 设置为false。
2. 消息在队列的存活时间超过设置的TTL时间。
3. 3. 消息队列的消息数量已经超过最大队列长度。 那么该消息将成为死信消息。如果配置了死信队列信息,那么该消息将会被丢进死信队列中,如果没有配置,则该 消息将会被丢弃
为每个需要使用死信的业务队列配置一个死信交换机,同一个项目的死信交换机可以共用一个,然后为每个业务队 列分配一个单独的routeKey,死信队列只不过是绑定在死信交换机上的队列,死信交换机也不是什么特殊的交换 机,只不过是用来接受死信的交换机,所以可以为任何类型 【Direct. Fanout. Topic]
TTL:一条消息或者该队列中的所有消息的最大存活时间
如果一条消息设置了TL属性或者进入了设置TTL属性的队列,那么这条消息如果在TTL设置的时间内没有被消费, 则会成为”死信”。如果同时配置了队列的TTL和消息的TTL,那么较小的那个值将会被使用。 只需要消费者一直消费死信队列里的消息
rabbitmq可以直连队列么?
生产者和消费者使用相同的参数声明队列。重复声明不会改变队列
RabbitMQ如何保证消息的可靠性传输
1、使用事务消息
2、使用消息确认机制
发送方确认:
channel设置为confirm模式,则每条消息会被分配一个唯一id
消息投递成功,信道会发送ack给生产者,包含了id,回调ConfirmCallback接口
如果发生错误导致消息丢失,发生nack给生产者。回调ReturnCallback接口
ack和nack只有一个触发,且只有一次,异步触发。可以继续发送消息
接收方确认:
声明队列时,指定noack=false, broker会等待消费者手动返回ack、才会删除消息,否则立刻删除
broker的ack没有超时机制,只会判断链接是否断开,如果断开、消息会被重新发送
RabbitMQ如何确保消息发送?消息接收?(异步)
发送方确认机制:
信道需要设置为 confirm 模式,则所有在信道上发布的消息都会分配一个唯一ID。
一旦消息被投递到queue(可持久化的消息需要写入磁盘),信道会发送一个确认给生产者(包含消息唯一ID).
如果 RabbitMQ 发生内部错误从而导致消息丢失,会发送一条 nack(未确认)消息给生产者。
所有被发送的消息都将被 confirm(即 ack) 或者被nack一次。但是没有对消息被 confirm 的快慢做任何保证,并 且同一条消息不会既被 confirm又被nack
发送方确认模式是异步的,生产者应用程序在等待确认的同时,可以维绩发送消息。当确认消息到达生产者,生产者的回调 方法会被触发。
Confirmcallback接口:只确认是香正确到达 Exchange 中,成功到达则回调 Returncallback接口:消息失败返回时回调
接收方确认机制:
消费者在声明队列时,可以指定noAck参数,当noAck=false时,RabbitMQ会等待消费者显式发回ack信号后才从内存 (或者磁盘,持久化消息中移去消息。香则, 消息被消费后会被立即删除。
消费者接收每一条消息后都必须进行确认(消息接收和消息确认是两个不同操作)。只有消费者确认了消息,RabbitmQ 才能安全地把消思从队列中删除。
RabbitMQ不会为未ack的消息设買超时时间,它判断此消,息是香需要重新投递给消费者的唯一依据是消费该消息的消费者 连接是否已经断开。这么设计的原因是RabbitwQ允许消费者消效一条消忌的时间可以很长。保证数据的最终一致性:
如果消费者返回ack之前街开了链接,RabbitwQ 会重新分发给下一个订阅的消费者。〈可能存在消息重复消费的的惠, 需要去重)
可以key为唯一id 存储reids中
(确保数据的一直 ,限流) tcp长链接
RabbitMQ事务消息
RabbitMQ事务消息
通过对信道的设置实现
- channel.txSelect0;通知服务器开启事务模式;服务端会返回Tx.Select-ok
- channel.basicPublish;发送消息,可以是多条,可以是消费消息提交ack
-
- channel.txCommit0提交事务;
- channel.txRollbacko回滚事务;
消费者使用事务:
- autoAck=false,手动提交ack,以事务提交或回滚为准;
- autoAck=true,不支持事务的,也就是说你即使在收到消息之后在回滚事务也是于事无补的,队列已经把消 息移除了
如果其中任意一个环节出现问题,就会拋出loException异常,用户可以拦截异常进行事务回滚,或决定要不要重 复消息。
事务消息会降低rabbitmq的性能(事务消息会发送到临时队列中)
RocketMQ 如何保证不丢消息
生产者:
同步阻塞的方式发送消息,加上失败重试机制,可能broker存储失败,可以通过查询确认 • 异步发送需要重写回调方法,检查发送结果_ ack机制,可能仔储COrTTTictug,存储ConsumerQueue失败,此时对消费者不可见
broker:同步刷盘、集群模式下采用同步复制、会等待slave复制完成才会返回确认
消费者:
offset手动提交,消息消费保证幂等