rabbitmq
基础概念
Exchange:交换机,接收消息,根据路由键转发消息到绑定的队列。它指定消息按什么规则,路由到哪个队列。
Binding:Exchange和Queue之间的虚拟连接,binding中可以包含routing key。用于消息队列和交换器之间的关联。一个绑定就是基于路由键将交换器和消息队列连接起来的路由规则,所以可以将交换器理解成一个由绑定构成的路由表。它的作用就是把exchange和queue按照路由规则绑定起来。
Routing key:一个路由规则,虚拟机可用它来确定如何路由一个特定消息。exchange根据这个关键字进行消息投递。
Queue:也称为Message Queue,消息队列,用来保存消息直到发送给消费者。它是消息的容器,也是消息的终点。一个消息可投入一个或多个队列。消息一直在队列里面,等待消费者连接到这个队列将其取走。
简单
工作
交换机
路由
主题
6.工作模式总结
这五种工作模式,可以归为三类:
- 生产者,消息队列,一个消费者;
- 生产者,消息队列,多个消费者;
- 生产者,交换机,多个消息队列,多个消费者;
7、四种交换器
1、direct 如果路由键完全匹配的话,消息才会被投放到相应的队列。
2、fanout 当发送一条消息到fanout交换器上时,它会把消息投放到所有附加在此交换器上的队列。
3、topic 设置模糊的绑定方式,“*”操作符将“.”视为分隔符,匹配单个字符;“#”操作符没有分块的概念,它将任意“.”均视为关键字的匹配部分,能够匹配多个字符。
4、header 交换器允许匹配 AMQP 消息的 header 而非路由键,除此之外,header 交换器和 direct 交换器完全一致,但是性能却差很多,因此基本上不会用到该交换器
如何保证消息不被重复消费?
保证消息不被重复消费的关键是保证消息队列的幂等性,这个问题针对业务场景来答分以下几点:
1.比如,你拿到这个消息做数据库的insert操作。那就容易了,给这个消息做一个唯一主键,那么就算出现重复消费的情况,就会导致主键冲突,避免数据库出现脏数据。
2.再比如,你拿到这个消息做redis的set的操作,那就容易了,不用解决,因为你无论set几次结果都是一样的,set操作本来就算幂等操作。
3.如果上面两种情况还不行,上大招。准备一个第三方介质,来做消费记录。以redis为例,给消息分配一个全局id,只要消费过该消息,将<id,message>以K-V形式写入redis。那消费者开始消费前,先去redis中查询有没消费记录即可
1生产者丢数据
生产者的消息没有投递到MQ中怎么办?从生产者弄丢数据这个角度来看,RabbitMQ提供transaction和confirm模式来确保生产者不丢消息。
2.消息队列丢数据
处理消息队列丢数据的情况,一般是开启持久化磁盘的配置。这个持久化配置可以和confirm机制配合使用,你可以在消息持久化磁盘后,再给生产者发送一个Ack信号。这样,如果消息持久化磁盘之前,rabbitMQ阵亡了,那么生产者收不到Ack信号,生产者会自动重发。
3.消费者丢数据
启用手动确认模式可以解决这个问题
所以一般来说,如果你要确保说写 RabbitMQ 的消息别丢,可以开启 confirm 模式,在生产者那里设置开启 confirm 模式之后,你每次写的消息都会分配一个唯一的 id,然后如果写入了 RabbitMQ 中,RabbitMQ 会给你回传一个 ack 消息,告诉你说这个消息 ok 了。如果 RabbitMQ 没能处理这个消息,会回调你的一个 nack 接口,告诉你这个消息接收失败,你可以重试。而且你可以结合这个机制自己在内存里维护每个消息 id 的状态,如果超过一定时间还没接收到这个消息的回调,那么你可以重发。
或者生产端与消费端开启定时任务去比对
Kafka
broker
顾名思义,集群中的一台机器,节点
zk
节点需要注册进去zk管理node,portition
consumer-group
消费组,多个消费者
consumer
消费者,当然也有生产者,组
topic
生产者发送到topic,消费者再去消费
partition
分区,各种中间件都有分区,这里就不解释,由topic决定保留在哪个分区,portition之间无法保证消费顺序
leader
分区的领导者
flowwer
副本,用于冗余数据,保证高可用
生产者消息丢失
Kafka消息发送有两种方式:同步(sync)和异步(async),默认是同步方式,可通过producer.type属性进行配置
0—不进行确认
1—表示当Leader接收成功时确认,其实还用最低水位的用于同步,这个时候会有数据丢失,(应用层处理)
-1—表示Leader和Follower都接收成功时确认(最稳妥)
消费者消息丢失
消息丢失:
同步模式下,确认机制设置为-1,即让消息写入Leader和Follower之后再确认消息发送成功
消费者:(offset手动提交,业务逻辑成功处理后,提交offset)
异步模式下,为防止缓冲区满,可以在配置文件设置不限制阻塞超时时间,当缓冲区满时让生产者一直处于阻塞状态
消息重复:将消息的唯一标识保存到外部介质中,每次消费时判断是否处理过即可。
应用场景
rabbitMQ支持对消息的可靠的传递,支持事务,不支持批量的操作;基于存储的可靠性的要求存储可以采用内存或者硬盘。金融场景中经常使用
kafka具有高的吞吐量,内部采用消息的批量处理,zero-copy机制,数据的存储和获取是本地磁盘顺序批量操作,具有O(1)的复杂度(与分区上的存储大小无关),消息处理的效率很高。(大数据)