赞
踩
目录
全称(message queue)消息队列,一个用于接收消息、存储消息并转发消息的中间件
多用于解决异步、削峰、解耦等场景,是能接收消息并转发消息
总之MQ是可以存放消息并转发消息的中间件,场景取决于拿这个能力去解决什么问题
MQ向别人承诺的场景是接收消息,存储,并可以转发消息
接收消息
在发送消息的时候,指明我要发送给谁,就像发送短信一样,你需要指明你要发送给谁?
这种方案在使用中是有问题的,因为在现在业务很多场景中, 发送方其实根本不知道对方是谁,他只是将自己的状态发送出来,那么谁需要这个消息,谁就接收,第二个如果指明了接收方,那么以后增加一个接收方就要改一下配置或者代码,将发送消息的人跟接收消息的人绑定在一起了
那么有没有方案,解耦的最好办法就是中间人,也叫中间层,我只发送给第三方,谁要消息,问第三方要,那么相当于我把发送的目标改为发送给第三方,这里的第三方就是mq,为了说明说明发送的地方,mq引入了topic的概念,发送方把消息发送到mq指定的一个通道中,以后谁想要这个消息,就跟mq说我想要这个通道的消息,也就是发送方发送的消息。
消费消息
消费消息,那么同理的一个问题,谁消费消息,为了说明那么mq需要引入一个概念,叫做消费者,也就是消费消息的服务,否则没有办法来区分是谁在接收消息,消费者通过网络接收消息就可以了,中间的细节我们先不探讨。
那么问题来了,消费者怎么说明消费谁的消息,上文已经说了,通过指明mq的topic,来决定我要哪一类消息。
至此我们总结一下最后的模型
也就是最后生产者和消费者通过MQ的topic概念来实现解耦。
说到存储,其实效率才是最主要的,容量不是我们关心的,但是说到存储,不只是mq,所有需要高效率的存储其实最后利用的核心都是一样的。
为什么随机写要转换为顺序写?
那么寻道时间比较长,如果是顺序写,只需要一次寻道时间,关于机械硬盘整个过程,读者可自行google。
为什么集中刷盘?
因为每次刷盘都会进行系统调用,第二还是跟硬盘的本身属性有关,无论是机械硬盘还是ssd按照一定块刷盘会比小数据刷盘效率更好。
为什么先说kafka的存储,因为kafka是第一个高性能的消息中间件,其中rocketmq也是借鉴于它,所以我们先说
1、为什么引入消费组概念?
上一次模型图我们还没有消费组,那么引入消费组,是因为现在一个服务都有很多实例在运行,消费组是对这群一群机器的一个划分,他还是一个概念而已。
2、mq内部也发生了变化,一个topic后面又对应了很多partition,partition也是一个概念,他只不过是把一个topic分成了很多份,每一份叫一个partition,你高兴也可以叫他xxx,那么我们来说说为什么要分成很多份,一份不行吗?
因为现在一个服务有很多实例在运行,如果topic只有一份的话,那么所有的实例都会来消费消息,并且都是抢占我们一个topic,这不可避免引入了多实例竞争,以及他们之间怎么协调,一堆问题需要关注解决,现在我把topic分成了很多份,每一份只给一个实例,那么就不会引入各实例之间的竞争问题了,简化了mq的问题。
3、生产组的引入也是一样的,只不过是一组机器的一个概念,一个逻辑的划分,生产者发送消息原先是发往topic,那么现在topic分成了很多份,生产者发送消息,需要说明发往哪个partition或者随意分配都可以,只不过最终发送的消息,会到一个topic下的一份里面。无论使用哪种映射方式都可以。
那么模型出来了,我们说说存储的问题。
对于kafka,一个partition对应一个文件,每次消息来都是顺序写这个文件。并且是定时刷盘,而不是每次写都刷盘,所以kafka的写非常高效。
rocketmq借鉴于kafka,所以存储借鉴了kafka,但是rocketmq不是仅仅把partition改成了ConsumeQueue,原先kafka,里面partition存储的是整个消息,但是现在ConsumeQueue里面是存储消息的存储地址,但是不存储消息了;
现在每个ConsumeQueue存储的是每个消息在commitlog这个文件的地址,但是消息存在于commitlog中
也就是所有的消息体都写在了一个文件里面,每个ConsumeQueue只是存储这个消息在commitlog中地址。
1、存储形式
2、存储可靠性
3、顺序消息
Kafka和RocketMQ都仅支持单topic分区有序。RocketMQ官方虽宣称支持严格有序,但方式为使用单个分区。
4、延时消息
5、消息重复
6、消息过滤
7、消息失败重试
8、DLQ(dead letter queue)
9、回溯消费
9、事务
10、服务发现
11、高可用
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。