比如用户注册,注册完成后发送通知邮件。如果不使用消息队列:
1.检查用户注册信息的合法性,如果合法则将注册信息写入数据库中,若不合法,直接返回,流程结束;
2.将用户注册信息写入数据库后,给用户发送通知邮件,以告知用户注册的相关信息,比如注册账号等信息。
注册消息写入数据库和发送通知邮件这两个组件间是直接交互,且是同步通信方式。那么,从用户提交注册到收到响应,需要等系统完成这两个步骤。
引入消息队列作为注册消息写入数据库和发送通知邮件这两个组件间的中间通信者,那么这两个组件就可以实现异步通信、异步执行。
1.检查用户注册信息的合法性,如果合法则将注册信息写入数据库中,若不合法则直接返回,流程结束;
2.注册消息写入消息数据库后,将消息写入消息队列的队尾;
3.发送通知邮件的组件去消息队列取出队首的消息,给用户发送通知邮件,告知用户注册的相关信息。
也就是说,采用消息队列模式,只需要第 2 步完成,即可给用户返回响应。第 3 步发送通知邮件可以在返回响应之后执行。
用户的注册信息写入数据库之后,通过数据库的可靠性设计来保证用户注册信息不会丢失,也就是说发送通知邮件的组件一定可以获取到用户注册信息,即保证会给注册用户发送通知邮件。也就是说,消息队列的引入不会影响用户注册网站,但会提升用户响应效率。
消息队列是基于队列实现的,存储具有特定格式的消息数据,比如定义一个包含消息类型、标志消息唯一性的 ID、消息内容的一个结构体作为消息数据的特定格式。消息以特定格式放入这个队列的尾部后可以直接返回,并不需要系统马上处理,之后会有其他进程从队列头部开始读取消息,按照消息放入的顺序逐一处理。
消息队列工作原理
生产者。生产者会产生消息或数据,并将消息或数据插入到消息队列中。
消息队列。一种具有先进先出特点的数据结构,用于存储消息。
消费者。从消息队列中获取消息或数据,进行相关处理。
RocketMQ 消息队列原理及工作机制
RokcetMQ 共包括 NameServer Cluster、Producer Cluster、Broker Cluster 和 Consumer Cluster 共 4 部分
NameServer Cluster,名字服务器集群。提供分布式服务的协同和管理功能,在 RocketMQ 中主要是管理 Broker 的信息,包括有哪些 Broker、Broker 的地址和状态等,以方便生产者获取 Broker 信息发布消息,以及订阅者根据 Broker 信息获取消息。
Producer Cluster,生产者集群。负责接收用户数据,然后将数据发布到消息队列中心 Broker Cluster。
Consumer Cluster,消费者集群。负责从 Broker 中获取消息进行消费。
Broker Cluster,Broker 集群。负责存储 Producer Cluster 发布的数据,以方便消费者进行消费。
在 Broker Cluster 中,消息的存储采用主题(Topic)+ 消息队列(Queue)的方式实现:
一个主题可以分区,分布在各个不同的 Broker 中,每个 Broker 上只有该主题的部分数据。每个主题分区中,队列的数量可以不同,由用户在创建主题时指定。队列是资源分配的基本单元,消息进行存储时会存放到相应主题的分区中。
RocketMQ 的工作流程
1.首先启动 NameServer,然后启动 Broker。Broker 启动后,会主动找 NameServer 建立连接,并将自己的信息注册到 NameServer 上。注册完毕后,Broker 会周期性地给 NameServer 发送心跳包,比如每隔 1s 发送一次,以告知 NameServer 自己还活着;心跳包里还可以包括 Broker 当前存储的数据信息,也就是说 Broker 可以周期性地向 NameServer 更新自己的数据信息,以保证 NameServer 上存储的数据是最新的。
2,创建主题,并确定这个主题的数据放入哪些 Broker 中。
3.当 Producer 生产消息发送到主题时,需要先到 NameServer 查询该主题存放在哪些 Broker 中,获取到相关 Broker 信息后,将消息发送给这些 Broker 进行存储。
4.Consumer 要从主题消费消息,也需要首先到 NameServer 查询一下该主题的消息存储在哪些 Broker 上,然后去相应的 Broker 获取消息进行消费。
消息队列模式,是根据消费者需求到消息队列获取数据消费的,消费者只需要知道消息队列地址即可,消息队列中心也无需提前知道消费者信息。消息队列这种模式对消费者没有特别需求,因此比较适合消费者为临时用户的场景。比如目前,阿里内部将 RocketMQ 应用于购物交易、充值、消息推送等多个场景,因为在这些场景下,每个消费者不是常驻进程或服务,几乎都是临时存在。
消息队列模式中采用了具有先进先出特征的队列结构进行存储,而订阅发布采用了 map 或数组等方式存储。
对于消息队列模式,消息队列中心无需提前获取消费者信息,因此对消费者比较灵活,适合消费者为临时用户的场景;
发布订阅模式,需要消费者提前向消息中心订阅消息,也就是说消息中心需要提前获取消费者信息,适合消费者为长驻进程或服务的场景。