消息队列的简单介绍
文章目录
一、什么是消息队列
消息队列可以简单理解为:把要传输的数据放在队列中。当我们需要使用消息的时候可以取出消息供自己使用。消息队列是分布式系统中重要的组件。
二、为何使用消息队列
使用消息队列主要是为了通过异步处理提高系统性能和削峰、降低系统耦合性。
1.解耦
系统A将userId写到消息队列中,系统C和系统D从消息队列中拿数据
例如,系统D拿userId不再经过系统A,而是从消息队列里边拿。系统D即便挂了或者请求超时,都跟系统A无关,只跟消息队列有关。
这样一来,系统A与系统B、C、D都解耦了
2.异步(减少响应所需时间)
为了提高用户体验和吞吐量,其实可以异步地调用系统B、C、D的接口。系统A执行完了以后,将userId写到消息队列中,然后就直接返回了。再由消息队列的消费者进程从消息队列中获取数据,各自执行自己的进程,因此响应速度得到大幅改善。
3.削峰/限流
系统B和系统C根据自己的能够处理的请求数去消息队列中拿数据,这样即便有每秒有8000个请求,那只是把请求放在消息队列中,去拿消息队列的消息由系统自己去控制,这样就不会把整个系统给搞崩。
可以得出,消息队列具有很好的削峰作用的功能——即通过异步处理,将短时间高并发产生的事务消息存储在消息队列中,从而削平高峰期的并发事务。
三、消息队列的缺点
1.系统复杂性提高
加入消息队列后,你需要考虑消息重复消费、消息丢失、消息的顺序消费等等问题!
2.系统可用性降低
这里先说一下什么是系统可用性,避免与系统复杂性弄混淆。
系统的可用性,英文名字为System Usability,即系统服务不中断运行时间占实际运行时间的比例。所以,可用性其实是一个百分比,如99.9%。
引入消息队列后,其作为一个中间件,万一MQ宕机,消息生产者,消息消费者都不能正常执行了。
3.数据一致性问题
消息队列可以实现异步,消息队列带来的异步确实可以提高系统响应速度。但是,万一消息的真正消费者并没有正确消费消息怎么办?这样就会导致数据不一致的情况了!
四、消息队列的相关概念
•Producer:消息⽣产者,负责消息的产⽣,由业务系统负责产⽣。
•Consumer:消息消费者,负责消息消费,由后台业务系统负责异步消费。
•Topic:消息的逻辑管理单位。
这三者是RocketMq中最最基本的概念。Producer是消息的⽣产者。Consumer是消息的消费者。消息通过Topic进⾏传递。Topic存放的是消息的逻辑地址。
具体来说是Producer将消息发往具体的Topic。Consumer订阅Topic,主动拉取或被动接受消息,如果Consumer消费消息失败则默认会重试16次。
五、 各种MQ产品的比较
常见的MQ产品包括Kafka、ActiveMQ、RabbitMQ、RocketMQ。
六、 RocketMQ模型
部署模型
1.注册中⼼Nameserver启动
2.消息中转服务Broker启动
3.消息⽣产者Produer启动
4.消息消费者Consumer启动
消息发送的步骤:
1.创建DefaultMQProducer
2.设置Namesrv地址
3.开启DefaultMQProducer
4.创建消息Message
5.发送消息
6.关闭DefaultMQProducer
注意事项
同步刷盘与异步刷盘:
RocketMQ的消息是存储到磁盘上的,这样既能保证断电后恢复,⼜可以让存储的消息量超出内存的限制。
RocketMQ为了提⾼性能,会尽可能地保证磁盘的顺序写。消息在通过Producer写⼊RocketMQ的时候,有两种写磁盘式:
•异步刷盘:在返回写成功状态时,消息可能只是被写⼊了内存中,写操作的返回快,吞吐量⼤;当内存⾥的消息量积累到⼀定程度时,统⼀触发写磁盘操作,快速写⼊。
•同步刷盘:在返回写成功状态时,消息已经被写⼊磁盘。具体流程是,消息写⼊内存后,⽴刻通知刷盘线程刷盘,然后等待刷盘完成,刷盘线程执⾏完成后唤醒等待的线程,返回消息
写成功的状态。