SpringCloud 学习目前已经进入到了消息总线这块了,很抱歉,因为之前没有对消息队列这块有很深的了解。看起来比较吃力,就合上书,来把消息队列相关的东西在看一遍。
什么是消息队列(Message Queue)?
队列我们知道是一种先进先出的数据结构,而消息队列我们可以把它看成是一个存放消息的容器,而这种容器也是先进先出的。更重要的是,这个容器针对消息生产者和消息消费者是异步进行的(作用是减少响应时间和解耦),并且可以暂时存储消息,直到该消息被消费。消息生产者只管把消息放入消息队列, 而最终谁来消费这不是他关心的。消息消费者只管从消息队列中拉取消息并消费,消息是谁产生的它也不关心。
消息队列主要解决了应用耦合、异步处理、流量削锋等问题。
耦合,异步大家应该都清楚,那么流量消锋是什么呢?(主要对于不知道的道友)最常见的电商秒杀活动,比如10:00开始秒杀,10:00大量请求涌入(高并发),我们知道服务器的处理资源是有限的,所以出现峰值的时候很容易造成服务器宕机,造成用户无法访问的情况。
流量削锋从本质上来说就是尽可能的延缓请求,遵从最后落地到数据库中的请求要尽可能的少的原则。
而消息队列则是我们最容易想到的解决上述问题的方案。
比如秒杀时间大量的请求涌入,我们通过异步的方式把海量的消息从一端放入队列,而队列的出口则平滑的处理请求,从而达到一个缓冲的作用,也保证请求最终都能得到处理。
(画的有点搞笑,大家别见笑)
对于消息队列用到的场景可以点这里
目前有许多mq产品,比如activemq,rocketmq,kafka等。本章我们专门来介绍一下RocketMQ。
( RocketMQ作为阿里开源的一款高性能、高吞吐量的消息中间件,经过了双十一,双十二等考验,性能上绝对是可靠的 )
先看一下RocketMQ的架构图
接下来我们了解几个概念
1、NameServer
NameServer在集群中他们是相互独立的,没有主从之分,单个NameServer节点中存储了活跃的Broker信息(Broker之间存在心跳)
2、Broker
Broker提供基本业务,单个Broker节点与所有的NameServer节点保持长连接以及心跳,并定时将Topic信息注册到NameServer上去。
Broker集群中分为两种角色master和slave(主从)。每个master可以对应多个slave,但一个slave只能对应一个master,master和slave通过指定相同的Brokername,不同的BrokerId (master为0)成为一个组。master和slave之间的同步方式分为同步双写和异步复制。
Borker中还有两个概念 :Topic、Queue
Topic是Queue的集合,而Queue是消息的物理管理单位。一个Topic下可以有多个Queue,Queue的引入使得消息存储可以分布式集群化,具有了水平扩展的能力。(这块讲的不太好,我没找到合适的描述方式,下来随着深入了解我会用更明晰的话解释)
3、Producer
3.1 Producer与NameService的关系
单个Producer与一个NameService保持长连接,并没有心跳。如果NameServer挂掉,那么Producer会自动查找新的NameServer,直到连接成功。Producer定期从NameService查询Topic配置信息。
3.2 Producer与Broker的关系
单个Producer与其相关的所有Broker保持长连接,还有心跳。消息发送的时候采用负载均衡(轮询方式),从而均匀发送到对应Topic下的所有Queue中。
4、Consumer
4.1 Consumer与NameServer的关系
单个Consumer与一个NameService保持长连接,并没有心跳。如果NameServer挂掉,那么Consumer会自动查找新的NameServer,直到连接成功。Consumer定期从NameService查询Topic配置信息。
4.2 Consumer与Broker的关系
一个Consumer与其相关的Broker保持长连接和心跳。失去心跳后,则关闭连接,并向该消费者分组的所有消费者发出通知,分组内消费者重新分配队列继续消费。
5、生产者组和消费者组的关系
可以看到同一生产者组产生同一个Topic主题,然后放置到不通的队列中,最终消费者组通过负载均衡从队列中消费相关联Topic主题然后分配队列消费。
(中间各个组件中涉及到很多配置,大家可以再深究一下,这里就不进行一一解释了)