RocketMQ

RocketMQ 是一款低延迟,高可靠,易于使用的消息中间件

什么是消息队列?为什么要用RocketMQ?

消息队列中间件是分布式系统中重要的组件,是一种“先进先出”的数据结构,主要解决应用解耦,流量削锋,数据分发,异步处理等问题,实现高性能,高可用,可伸缩和最终一致性架构。目前使用较多的消息队列有ActiveMQ,RabbitMQ,ZeroMQ,Kafka,MetaMQ,RocketMQ

应用解耦

系统的耦合性越高,容错率越低,用户创建订单后,如果后续的库存系统无法访问,则订单减库存失败,从而导致订单创建失败,订单系统与库存系统耦合。
引入消息队列后:
订单系统:用户下单后,订单系统完成持久化处理,将消息写入消息队列,返回用户订单下单成功
库存系统:订阅下单的消息,采用推/拉的方式,获取下单信息,库存系统根据下单信息,进行库存操作
假如:在下单时库存系统无法正常使用,也不影响正常下单,因为下单后,订单系统写入消息队列就不在关心后续的操作了。实现订单系统与库存系统的应用解耦

流量削峰

应用系统如果遇到系统请求流量的瞬间猛增,有可能将系统压垮。有了消息队列可以将大量请求缓存起来,分散到很长一段时间处理,这样可以大大提高系统的稳定性和用户体验。
一般情况,为了保证系统的稳定性,如果系统负载超过阈值,就会阻止用户请求,这会影响用户体验,而如果使用消息队列将请求缓存起来,等待系统处理完毕后通知用户下单完毕,这样总比不能下单比较好。

处于经济考量目的:
业务系统正常的QPS(每秒处理请求数)如果是1000,流量最高峰是10000,为了应对流量高峰配置高性能的服务器显然不划算,这时可以使用消息队列对峰值流量削峰。

例如:每秒5K请求数量,此时先通过MQ缓存起来,然后A系统从MQ中每秒拉取2K个请求进行处理。

数据分发

通过消息队列可以让数据在多个系统之间进行流通,数据的产生方不要关心谁来使用数据,只需要将数据发送到消息队列,数据使用方直接在消息队列中获取数据即可。

异步处理

场景说明:用户注册后,需要发注册邮件和注册短信。传统的做法有两种:
1、串行的方式:将注册信息写入数据库后,再发送注册邮件,再发送注册短信,三个任务全部完成后,返回给客户端。
2、并行方式:将注册信息写入数据库后,发送注册邮件,发送注册短信。以上三个信息完成后,返回给客户端。与串行的差别是,并行加快了处理的时间。

假设三个业务节点每个使用50毫秒,串行的时间则是150毫秒,并行的时间可以假设为100毫秒,而引入消息队列后,当用户注册后,先将注册信息写入数据库,然后将发送邮件、发送短信写入消息队列后,直接返回结果,此时大大降低了用户的响应时间,然后发送邮件和发送短信再异步读取消息队列中的数据进行处理。

消息通讯

点对点通讯:客户端A和客户端B使用同一队列,进行消息通讯
聊天室通讯:客户端A、客户端B、客户端N订阅同一主题,进行消息发布和接收,实现类似聊天室效果。
MQ的优点和缺点
优点:应用解耦、流量削峰、数据分发
缺点包含以下几点:
1、系统可用性降低
系统引入的外部依赖越多,系统稳定性越差,一旦MQ宕机,就会对业务造成影响。
2、系统复杂度提高
MQ的加入大大增加了系统的复杂度,以前系统间是同步的远程调用,现在是通过MQ进行异步调用。
3、一致性问题
A系统处理完业务,通过MQ给B、C、D三个系统发消息数据,如果B、C系统处理成功,D系统处理失败,那么↓
如何保证消息数据处理的一致性?

问题解答
1、如何保证MQ高可用?

消费端的高可用:
在Consumer的配置文件中,并不需要设置是从Master读还是从Slave 读,当Master不可用或者繁忙的时候,Consumer会被自动切换到从Slave 读。有了自动切换Consumer这种机制,当一个Master角色的机器出现故障后,Consumer仍然可以从Slave读取消息,不影响Consumer程序。这就达到了消费端的高可用性。

发送端的高可用:
在创建Topic的时候,把Topic的多个Message Queue创建在多个Broker组上(相同Broker名称,不同 brokerId的机器组成一个Broker组),这样当一个Broker组的Master不可用后,其他组的Master仍然可用,Producer仍然可以发送消息。RocketMQ目前还不支持把Slave自动转成Master,如果机器资源不足,需要把Slave转成Master,则要手动停止Slave角色的Broker,更改配置文件,用新的配置文件启动Broker

2、如何保证消息数据处理的一致性?

RocketMQ中各角色介绍
Producer:消息的发送者
Consumer:消息的接收者
Consumer Group:消费组,每一个Consumer实例都属于一个Consumer Group,每一条消息只会被同一个Consumer Group中的一个Consumer实例消费。(不同Consumer Group可以同时消费同一条消息)
Broker:暂存和传输消息 举例:快递公司
NameServer:管理Broker 举例:快递公司的管理机构
Topic:区分消息的种类,一个发送者可以发送给一个或者多个Topic,一个接收者也可以订阅一个或者多个Topic消息
Message Queue:相当于是Topic的分区;用于并行发送和接收消息

NameServer

名称服务,是 RocketMQ 的路由中心,用于 Broker 服务的注册和发现,类似 Zookeeper 但是比 Zookeeper 性能更好,实现也更简单,因为 NameServer 集群中的服务器都是独立的,各实例间相互不进行信息通讯

NameServer 的作用

NameServer 是 RocketMQ 的大脑,主要用于管理Broker(相当于快递公司的管理机构)
路由注册:
所有的 Broker 实例信息都需要注册到每一个 NameServer 服务中,就相当于一个 Broker 需要与 NameServer 集群中的每一台服务器都要保持连接。

RocketMQ 的路由注册是通过 Broker 和 NameServer 的心跳机制实现的。Broker 启动时会向 NameServer 集群每台机器发送心跳包,后续每隔 30 秒发送一次心跳包给 NameServer 集群

路由发现:

Client(producer 和 consumer)只需要随机选择 NameServer 集群中一台服务器保持连接,通过这一个 NameServer 实例获取到 Broker 实例信息再与 Broker 进行连接

路由发现是非实时的,Broker 推送路由信息给 NameServer,NameServer 并不会立马将路由信息推送给客户端,而是由客户端自己定时去拉取

路由删除:

NameServer 启动的时候有个定时任务扫描存活 Broker。NameServer 会每隔 10 秒扫描一次 BrokerLiveInfo,如果 lastUpdateTimestamp 在当前时间 120 秒之前,lastUpdateTimestamp 已经有 120 秒没有更新了,那么就会移除该 broker

Broker

Broker 是 RocketMQ 的核心,是一个单独的服务,主要负责消息的持久化存储、转发(接收 Producer 发过来的消息、处理 Consumer 的消费消息请求)、消息的 HA 机制以及服务端过滤功能等(例如:可以理解为快递公司)
消息发送:
消息发送类型分为三种
1、发送同步消息:这种可靠性同步消息使用的比较广泛 比如:重要消息通知,短信通知
通过send的返回值sendResult来判断获取是否发送成功
2、发送异步消息:异步消息通常在对响应事件比较敏感的业务场景下使用,即发送端不能容忍长时间的等待Broker的响应
通过回调方法OnSuccess和OnException来接收回调结果
3、发送单向消息:单向消息主要用于不特别关心发送结果的场景,如日志发送
没有任何返回结果

消费消息:

1、集群模式(负载均衡):消费者采用集群方式消费消息,一条消息同一个消费者组中只有一个消费者会消费到
2、广播模式:消费者采用广播方式消费消息,一条消息同一个消费者组中每个消费者都会消费

顺序消息:

消息有序指的是,消费者端消费消息时,需按照消息的发送顺序来消费,即先发送的消息,需要先消费(FIFO)。

举个例子:通常创建订单后,会经历一系列的操作:【订单创建 -> 订单支付 -> 订单发货 -> 订单配送 -> 订单完成】。在创建完订单后,会发送5条消息到MQ Broker中,消费的时候要按照刚才的顺序去消费,这样的订单才是有效的。

RocketMQ采用局部顺序一致性的机制,实现了单个队列中消息的有序性,使用FIFO顺序提供有序消息。简而言之,我们的消息要保证有序,就必须把一组消息存放在同一个队列,然后由Consumer进行逐一消费。

但是如果是在高并发的场景下,消息不就阻塞了吗?
RocketMQ给的解决方案是按照业务去划分不同的队列,然后并行消费,提高消息的处理速度的同时避免消息堆积
RocketMQ可以严格的保证消息有序,可以分为分区有序或者全局有序:
全局有序:全局顺序时使用一个queue;
分区有序:局部顺序时多个queue并行消费
在默认的情况下,消息发送会采取Round Robin(轮询调度算法)轮询方式把消息发送到不同的queue;而消费消息的时候从多个queue上拉取消息,这种情况发送和消费是不能保证顺序的。但是如果控制发送的顺序消息只依次发送到同一个queue中,消费的时候只从这个queue上依次拉取,则就保证了顺序。当发送和消费参与的queue只有一个,则是全局有序;如果多个queue参与,则为分区有序,即相对每个queue,消息都是有序的

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值