RocketMq概述

是什么?

RocketMQ是一个纯Java、分布式、队列模型的开源消息中间件,前身是MetaQ,是阿里参考Kafka特点研发的一个队列模型的消息中间件。2016年开源后捐赠给Apache, 2017年9月25日成为 apache 的顶级项目。

特点

灵活的扩展性

RocketMQ天然支持集群,其核心四大组件(NameServer、Broker,Producer、Consumer)的每一个都可以在没有单点故障的情况下进行水平扩展。

海量消息堆积能力

RocketMQ采用零拷贝原理实现了超大量消息的堆积能力,据说单机已经可以支持亿级消息堆积,而且在堆积了这么多消息后依然保持写入低延迟。

支持顺序消息

RocketMQ可以保证消息消费者按照消息发送的顺序对消息进行消费。顺序消息分为全局有序消息局部有序消息,一般推荐使用局部有序消息,即生产者通过将某一类消息按顺序发送至同一个队列中来实现。

支持多种消息过滤方式

消息过滤分为在服务器端过滤和在消费端过滤。在服务器端过滤时可以按照消息消费者的要求进行过滤,优点是减少了不必要的消息传输,缺点是增加了消息服务器的负担,实现相对复杂。消费端过滤则完全由具体应用自定义实现,这种方式更加灵活,缺点是很多无用的消息会被传输给消息消费者。

支持事务消息

这个特性对于分布式事务来说提供了另一种解决思路。

支持回溯消息

回溯消费是指对于消费者已经消费成功的消息,由于业务需求需要重新消费。RocketMQ支持按照时间回溯消费,时间维度精确到毫秒,可以向前回溯也可以向后回溯。

架构

在这里插入图片描述
rocketmq由四部分组成:name servers, brokers, producers and consumers。

NameServer

NameServer提供轻量级服务发现与注册。每个NameServer记录完整的路由信息,提供相应的读写服务,支持快速的存储扩展。

Producer在发送消息前从NameServer中获取Topic的路由信息也就是发往哪个Broker,Consumer也会定时从NameServer获取topic的路由信息,Broker在启动时会向NameServer注册,并定时进行心跳连接,且定时同步维护的Topic到NameServer。

NameServer相当于配置中心,维护Broker集群、Broker信息、Broker存活信息、主题与队列信息等。

每个NameServer节点之间相互独立,彼此之间不通信,每个Broker与集群内所有的Nameserver保持长连接

NameServer主要包括如下两部分:

Broker Management

NameServer接受来自Broker cluster的注册表,并提供心跳机制来检查代理是否处于活动状态。

Routing Management

每一个NameServer都将保存着所有的Broker cluster 和 queue 的路由信息。

Producer

消息由Producer通过多种负载均衡模式发送到Broker集群。

负载均衡策略

Producer的负载均衡是由MQFaultStratege.selectOneMessageQueue()来实现的。这个方法就是随机选择一个要发送消息的broker来达到负载均衡的效果,选择的标准:尽量不选刚刚选过的broker,尽量不选发送上条消息延迟过高或没有响应的broker,也就是找到一个可用的broker。

发送方式

RocketMQ 提供了三种方式发送消息:同步、异步和单向。

同步发送

同步发送指消息发送方发出数据后会在收到接收方发回响应之后才发下一个数据包。一般用于重要通知消息,例如重要通知邮件、营销短信。

异步发送

异步发送指发送方发出数据后,不等接收方发回响应,接着发送下个数据包,一般用于可能链路耗时较长而对响应时间敏感的业务场景。

单向发送

单向发送是指只负责发送消息而不等待服务器回应且没有回调函数触发,适用于某些耗时非常短但对可靠性要求并不高的场景,例如日志收集。

Broker

负责消息的存储、转发、消息查询以及HA保证等。它还存储与消息相关的元数据,包括用户组、消费进度偏移量、队列信息等。

Broker内部维护着一个个Message Queue,用来存储消息的索引,真正存储消息的地方是CommitLog(日志文件)。

单个Broker节点与所有的NameServer节点保持长连接及心跳,并会定时将Topic信息注册到NameServer,底层的通信和连接都是基于Netty实现的。

具有上亿级消息堆积能力,同时可严格保证消息的有序性。

Broker 在实际部署过程中对应一台服务器,每个Broker 可以存储多个Topic的消息,每个Topic的消息也可以分片存储于不同的 Broker。MessageQueue 用于存储消息的物理地址,每个Topic中的消息地址存储于多个 Message Queue 中。

如下图所示,Broker 有几个重要的子模块:

  • Remoting Module(broker的入口)处理来自客户端的请求。
  • Client Manager,管理客户(Producer/Consumer)并维护消费者的主题订阅。
  • Store Service,提供简单的API在物理磁盘中存储或查询消息。
  • HA Service,提供主节点和从节点之间的数据同步功能。
  • Index Service,按指定键为消息建立索引,并提供快速消息查询。
    在这里插入图片描述

集群部署方案

Broker有Master和 Slave两种类型,其中 Master 既可以写,又可以读;Slave不可以写,只可以读。从物理结构上看,Broker 的集群部署有单Master、多Master、多Master 多 Slave (同步双写)、多Master 多 Slave(异步复制)等多种方式。

单 Master

采用这种方式,一旦 Broker重启或宕机就会导致整个服务不可用。这种方式风险较大,所以不建议在线上环境中使用。

多 Master

所有消息服务器都是 Master,没有Slave。这种方式的优点是配置简单,单个 Master 宕机或重启维护对应用无影响。缺点是在单台机器宕机期间,该机器上未被消费的消息在机器恢复之前不可订阅,消息的实时性会受到影响。

多Master多 Slave(同步双写)

为每个Master 都配置一个Slave,所以有多对Master-Slave,消息采用同步双写方式,主备都写成功了才返回成功。这种方式的优点是数据与服务都没有单点问题,Master 宕机时消息无延迟,服务与数据的可用性非常高;缺点是相对异步复制方式其性能略低,发送消息的延迟略高。

多Master 多 Slave(异步复制)

为每个 Master都配置一个Slave,所以有多对Master-Slave,消息采用异步复制方式,主备之间有毫秒级消息延迟。这种方式的优点是丢失的消息非常少,且消息的实时性不会受到影响,Master 宕机后消费者可以继续从Slave消费,中间的过程对用户应用程序透明,不需要人工干预,性能同多Master方式几乎一样。缺点是 Master 宕机后在磁盘损坏的情况下会丢失极少量的消息。

Consumer

消费模式

支持PUSH和PULL两种消费模式,支持集群消费和广播消息,提供实时的消息订阅机制。

Pull

拉取型消费者(Pull Consumer)主动从消息服务器拉取信息,只要拉取到消息,就会启动消费过程。所以 Pull 称为主动消费型。

Push

推送型消费者(Push Consumer)封装了消息的拉取、消费进度和其他的内部维护工作,将消息到达时执行的回调接口留给用户应用程序来实现。所以 Push 称为被动消费类型,但从实现上看还是从消息服务器中拉取消息,不同于 Pull 的是 Push 首先要注册消费监听器,监听器是要用户自行实现的。当消息达到broker服务器后,会触发监听器拉取消息,然后启动消费过程。

集群或广播

看业务需求,默认是集群消费。

集群消费(Clustering)

broker中的一条消息会发送给订阅这个topic的一个消费组里的唯一一个消费者进行消费。如果这个消费者挂掉了,组里的其他消费者会接替它进行消费。

广播消费(Broadcasting)

broker中的一条消息会发送给订阅这个topic的一个消费组里的每一个消费者进行消费。

负载均衡策略

Consumer的负载均衡是指将MessageQueue中的消息队列分配到消费者组里的具体消费者。
Consumer在启动的时候会实例化rebalanceImpl,这个类负责消费端的负载均衡。通过rebalanceImpl调用allocateMesasgeQueueStratage.allocate()完成负载均衡。
每次有新的消费者加入到组中就会重新做一下分配。每10秒自动做一次负载均衡。

基本概念

Message

一条消息必须有一个主题(Topic),主题可以看做是你的信件要邮寄的地址。

一条消息也可以拥有一个可选的标签(Tag)和额处的键值对,它们可以用于设置一个业务 Key 并在 Broker 上查找此消息以便在开发期间查找问题。

Topic

Topic,是消息的第一级类型,每条消息都有一个主题,就像信件邮寄的地址一样。Topic就是我们具体的业务,比如一个电商系统可以有订单消息,商品消息,采购消息,交易消息等。Topic和生产者和消费者的关系非常松散,生产者和Topic可以是1对多,多对1或者多对多,消费者也是这样。

一个 Topic 也可以被 0个、1个、多个消费者订阅。

Tag

Tag(标签)它是消息的第二级类型,用于为用户提供额外的灵活性。它的主要用途是在消费端的消息过滤。比如采购消息分为采购创建消息,采购审核消息,采购推送消息,采购入库消息,采购作废消息等,这些消息是同一Topic和不同的Tag,当消费端只需要采购入库消息时就可以用Tag来实现过滤,不是采购入库消息的tag就不处理。

Group

组,可分为ProducerGroup生产者组 和 ConsumerGroup消费者组,一个组可以订阅多个Topic。一般来说,某一类相同业务的生产者和消费者放在一个组里。

Producer Group

生产者组(Producer Group)是一类生产者的集合,这类生产者通常发送一类消息并且发送逻辑一致,所以将这些生产者分组在一起。从部署结构上看,生产者通过生产者组的名字来标识自己是一个集群。

ConsumerGroup

消费者组(Consumer Group)是一类消费者的集合,这类消费者通常消费同一类消息并且消费逻辑一致,所以将这些消费者分组在一起。消费者组与生产者组类似,都是将相同角色的消费者分组在一起并命名的。分组是一个很精妙的概念设计,RocketMQ正是通过这种分组机制,实现了天然的消息负载均衡。在消费消息时,通过消费者组实现了将消息分发到多个消费者服务器实例,比如某个Topic有9条消息,其中一个消费者组有3个实例(3个进程或3台机器),那么每个实例将均摊3条消息,这也意味着我们可以很方便地通过增加机器来实现水平扩展。

Queue

在Kafka中叫Partition,每个Queue内部是有序的,在RocketMQ中分为读和写两种队列,一般来说读写队列数量一致,如果不一致就会出现很多问题。

Message Queue

Topic只是个逻辑上的概念,消息队列是消息的物理管理单位,当发送消息的时候,Broker会轮询包含该Topic的所有消息队列,然后将消息发出去。有了消息队列,可以使得消息的存储可以分布式集群化,具有了水平的扩展能力。

Offset

是指消息队列中的offset,可以认为就是下标,消息队列可看做数组。offset是java long型,64位,理论上100年不会溢出,所以可以认为消息队列是一个长度无限的数据结构。

优缺点

优点

  • 单机吞吐量:十万级
  • 可用性:非常高,分布式架构
  • 消息可靠性:经过参数优化配置,消息可以做到0丢失
  • 功能支持:MQ功能较为完善,还是分布式的,扩展性好
  • 支持10亿级别的消息堆积,不会因为堆积导致性能下降
  • 源码是java,我们可以自己阅读源码,定制自己公司的MQ,可以掌控
  • 天生为金融互联网领域而生,对于可靠性要求很高的场景,尤其是电商里面的订单扣款,以及业务削峰,在大量交易涌入时,后端可能无法及时处理的情况
  • RoketMQ在稳定性上可能更值得信赖,这些业务场景在阿里双11已经经历了多次考验

缺点

  • 支持的客户端语言不多,目前是java及c++,其中c++不成熟
  • 没有在 mq 核心中去实现JMS等接口,有些系统要迁移需要修改大量代码

Linux命令

启动命令

# 1.启动nameserver 并查看日志
nohup sh bin/mqnamesrv &
tail -f ~/logs/rocketmqlogs/namesrv.log
# 2.启动Broker 并查看日志
nohup sh bin/mqbroker -n localhost:9876 autoCreateTopicEnable=true & 
tail -f ~/logs/rocketmqlogs/broker.log 

关闭命令

# 1.关闭Broker
sh bin/mqshutdown broker
# 2.关闭Nameserver
sh bin/mqshutdown namesrv

测试rocketmq

# 1.设置环境变量
export NAMESRV_ADDR=localhost:9876
# 2.生产者测试 模拟消息发送
sh bin/tools.sh org.apache.rocketmq.example.quickstart.Producer
# 3.消费者测试 模拟消息接收
sh bin/tools.sh org.apache.rocketmq.example.quickstart.Consumer

参考

书籍《分布式消息中间件实践》
博客 看完保送阿里的RocketMQ知识点(超详细)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值