本文主要介绍RocketMQ中Topic、Tag、GroupName的概念、设计初衷以及使用方法。

一.Topic

首先看看官方的定义:

Topic是生产者在发送消息和消费者在拉取消息的类别。Topic与生产者和消费者之间的关系非常松散。具体来说,一个Topic可能有0个,一个或多个生产者向它发送消息;相反,一个生产者可以发送不同类型Topic的消息。类似的,消费者组可以订阅一个或多个主题,只要该组的实例保持其订阅一致即可。

  • Topic表示一类消息的集合,每个主题包含若干条消息,每条消息只能属于一个主题,是RocketMQ进行消息订阅的基本单位。 topic:message 1:n message:topic 1:1
  • 一个生产者可以同时发送多种Topic的消息;而一个消费者只对某种特定的Topic感兴趣,即只可以订阅
    和消费一种Topic的消息。 producer:topic 1:n consumer:topic 1:1

在Producer中使用Topic:

Message msg = new Message("TopicTest" /* Topic */,"TagA",("Hello RocketMQ " + i).getBytes(RemotingHelper.DEFAULT_CHARSET));

在Consumer中订阅Topic:

consumer.subscribe("TopicTest", "*");

个人理解:

Topic 就是业务分类。一个Topic可以绑定在多个Broker上,生产者发送消息时,按照一定的策略发送到一个Broker上去

二.Tag

同样,先看看官方怎么定义的:

标签,换句话的意思就是子主题,为用户提供了额外的灵活性。有了标签,来自同一业务模块的具有不同目的的消息可以具有相同的主题和不同的标记。标签有助于保持代码的清晰和连贯,同时标签也方便RocketMQ提供的查询功能。

为消息设置的标签,用于同一主题下区分不同类型的消息。来自同一业务单元的消息,可以根据不同业务目的在同一主题下设置不同标签。标签能够有效地保持代码的清晰度和连贯性,并优化RocketMQ提供的查询系统。消费者可以根据Tag实现对不同子主题的不同消费逻辑,实现更好的扩展性。
Topic是消息的一级分类,Tag是消息的二级分类。

  • Topic:货物

    • tag=上海
    • tag=江苏
    • tag=浙江
      ------- 消费者 -----
      topic=货物 tag = 上海
      topic=货物 tag = 上海|浙江
      topic=货物 tag = *

    在Producer中使用Tag:

Message msg = new Message("TopicTest","TagA" /* Tag */,("Hello RocketMQ " + i).getBytes(RemotingHelper.DEFAULT_CHARSET));

在Consumer中订阅Tag:

// * 代表订阅Topic下的所有消息
consumer.subscribe("TopicTest", "TagA||TagB");

三.GroupName

和现实世界中一样,RocketMQ中也有组的概念。代表具有相同角色的生产者组合或消费者组合,称为生产者组或消费者组。

作用是在集群HA的情况下,一个生产者down之后,本地事务回滚后,可以继续联系该组下的另外一个生产者实例,不至于导致业务走不下去。在消费者组中,可以实现消息消费的负载均衡和消息容错目标。

另外,有了GroupName,在集群下,动态扩展容量很方便。只需要在新加的机器中,配置相同的GroupName。启动后,就立即能加入到所在的群组中,参与消息生产或消费。

在Producer中使用GroupName:

// 使用GroupName来初始化Producer,如果不指定,就会使用默认的名字:DEFAULT_PRODUCER
DefaultMQProducer producer = new DefaultMQProducer("group_name_1");

在Consumer中使用GroupName:

// 使用GroupName来初始化Consumer,如果不指定,就会使用默认的名字:DEFAULT_CONSUMER
DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("group_name_1");

RocketMQ使用Topic、Tag和GroupName简单的3个概念,就能实现这些功能,敬佩实现它的作者们。

四. Queue

存储消息的物理实体。一个Topic中可以包含多个Queue,每个Queue中存放的就是该Topic的消息。一个Topic的Queue也被称为一个Topic中消息的分区(Partition)。

一个Topic的Queue中的消息只能被一个消费者组中的一个消费者消费。或者一个Queue中的消息不允许同一个消费者组中的多个消费者同时消费。

在学习参考其它相关资料时,还会看到一个概念:分片(Sharding)。分片不同于分区。在RocketMQ中,分片指的是存放相应Topic的Broker。每个分片中会创建出相应数量的分区,即Queue,每个Queue的大小都是相同的。

既然Topic是队列的名字,那么queue就表示真实操作的队列了。一开始的时候一个Topic就对应一个queue,多好,一个是名字、一个是现实。可是用着用着就悲催了,为啥?消息操作太多了,全都怼在一个小队列上。为了提高效率,咋整??RocketMQ是这样做的,一个Topic绑定的是一组queue,这样每个queue分摊部分压力,性能就上去了。

读队列个数:可以用来读取数据的队列个数

写队列个数:可以用来写入数据的队列个数

queue:真实存储数据用的队列。

在创建或更改topic时,需要配置writeQueueNums和readQueueNums数,这里的读写队列有什么作用?

初识rocketmq的童鞋,很容易把读写队列和读写分离混淆在一起。其实在rocketmq里是完全不同的两个概念。读写分离,是用HA机制,将一个节点的数据同步到另外一个节点,主节点多用于写(也可读),从节点只用于读。往往一主多从,通过读写分离减轻系统压力。

读写队列,则是在做路由信息时使用。在消息发送时,使用写队列个数返回路由信息,而消息消费时按照读队列个数返回路由信息。在物理文件层面,只有写队列才会创建文件。举个例子:写队列个数是8,设置的读队列个数是4.这个时候,会创建8个文件夹,代表0 1 2 3 4 5 6 7,但在消息消费时,路由信息只返回4,在具体拉取消息时,就只会消费0 1 2 3这4个队列中的消息,4 5 6 7中的信息压根就不会被消费。反过来,如果写队列个数是4,读队列个数是8,在生产消息时只会往0 1 2 3中生产消息,消费消息时则会从0 1 2 3 4 5 6 7所有的队列中消费,当然 4 5 6 7中压根就没有消息 ,假设消费group有两个消费者,事实上只有第一个消费者在真正的消费消息(0 1 2 3),第二个消费者压根就消费不到消息。

由此可见,只有readQueueNums>=writeQueueNums,程序才能正常进行。最佳实践是readQueueNums=writeQueueNums。那rocketmq为什么要区分读写队列呢?直接强制readQueueNums=writeQueueNums,不就没有问题了吗?

rocketmq设置读写队列数的目的在于方便队列的缩容和扩容。思考一个问题,一个topic在每个broker上创建了128个队列,现在需要将队列缩容到64个,怎么做才能100%不会丢失消息,并且无需重启应用程序?

最佳实践:先缩容写队列128->64,写队列由0 1 2 …127缩至 0 1 2 …63。等到64 65 66…127中的消息全部消费完后,再缩容读队列128->64.(同时缩容写队列和读队列可能会导致部分消息未被消费)

五 消息标识(MessageId/Key)

RocketMQ中每个消息拥有唯一的MessageId,且可以携带具有业务标识的Key,以方便对消息的查询。
不过需要注意的是,MessageId有两个:在生产者send()消息时会自动生成一个MessageId(msgId),当消息到达Broker后,Broker也会自动生成一个MessageId(offsetMsgId)。msgId、offsetMsgId与key都称为消息标识。

  • msgId:由producer端生成,其生成规则为:
  • producerIp + 进程pid + MessageClientIDSetter类的ClassLoader的hashCode + 当前时间 + AutomicInteger自增计数器
  • offsetMsgId:由broker端生成,其生成规则为: brokerIp + 物理分区的offset(Queue中的偏移量)
  • key:由用户指定的业务相关的唯一标识
    1 Producer
    消息生产者,负责生产消息。Producer通过MQ的负载均衡模块选择相应的Broker集群队列进行消息投
    递,投递的过程支持快速失败并且低延迟。
    例如,业务系统产生的日志写入到MQ的过程,就是消息生产的过程
    再如,电商平台中用户提交的秒杀请求写入到MQ的过程,就是消息生产的过程
    RocketMQ中的消息生产者都是以生产者组(Producer Group)的形式出现的。生产者组是同一类生产
    者的集合,这类Producer发送相同Topic类型的消息。一个生产者组可以同时发送多个主题的消息。

六、系统架构


RocketMQ架构上主要分为四部分构成:

1 Producer

消息生产者,负责生产消息。Producer通过MQ的负载均衡模块选择相应的Broker集群队列进行消息投递,投递的过程支持快速失败并且低延迟。

例如,业务系统产生的日志写入到MQ的过程,就是消息生产的过程
再如,电商平台中用户提交的秒杀请求写入到MQ的过程,就是消息生产的过程

RocketMQ中的消息生产者都是以生产者组(Producer Group)的形式出现的。生产者组是同一类生产者的集合,这类Producer发送相同Topic类型的消息。一个生产者组可以同时发送多个主题的消息。

2 Consumer

消息消费者,负责消费消息。一个消息消费者会从Broker服务器中获取到消息,并对消息进行相关业务处理。

例如,QoS系统从MQ中读取日志,并对日志进行解析处理的过程就是消息消费的过程。
再如,电商平台的业务系统从MQ中读取到秒杀请求,并对请求进行处理的过程就是消息消费的过程。

RocketMQ中的消息消费者都是以消费者组(Consumer Group)的形式出现的。消费者组是同一类消费者的集合,这类Consumer消费的是同一个Topic类型的消息。消费者组使得在消息消费方面,实现负载均衡(将一个Topic中的不同的Queue平均分配给同一个Consumer Group的不同的Consumer,注
意,并不是将消息负载均衡)和容错(一个Consmer挂了,该Consumer Group中的其它Consumer可
以接着消费原Consumer消费的Queue)的目标变得非常容易。

消费者组中Consumer的数量应该小于等于订阅Topic的Queue数量。如果超出Queue数量,则多出的Consumer将不能消费消息。

不过,一个Topic类型的消息可以被多个消费者组同时消费。
注意,

  • 1)消费者组只能消费一个Topic的消息,不能同时消费多个Topic消息
  • 2)一个消费者组中的消费者必须订阅完全相同的Topic

RocketMQ 中Topic、Tag、GroupName基本概念介绍相关推荐

  1. [Java高并发系列(5)][详细]Java中线程池(1)--基本概念介绍

    1 Java中线程池概述 1.1 什么是线程池? 在一个应用当中, 我们往往需要多次使用线程, 这意味着我们需要多次创建和销毁线程.那么为什么不提供一个机制或概念来管理这些线程呢? 该创建的时候创建, ...

  2. rocketMq概念介绍

    rocketMq官网 http://rocketmq.apache.org/ rocketMq逻辑概念介绍 rocketMq逻辑图 备注:     改图片分享自李占卫的网上家园 说明: 在rocket ...

  3. 深入理解RocketMQ中的NameServer

    本文来说下RocketMQ中的NameServer 文章目录 NameServer介绍 NameServer的作用 为什么要使用NameServer NameServer如何保证数据的最终一致 路由注 ...

  4. MIPI简介(一)——基础概念介绍

    MIPI全称Mobile Industry Processor Interface,即移动产业处理器接口.MIPI联盟在2003年由ARM, Nokia, ST ,TI等公司成立,成员包括手机设备制造 ...

  5. Kafka中topic的Partition,Kafka为什么这么快,Consumer的负载均衡及consumerGroup的概念(来自学习笔记)

    1.1. Kafka中topic的Partition  在Kafka文件存储中,同一个topic下有多个不同partition,每个partition为一个目录,partiton命名规则为topic ...

  6. SQL Server 中WITH (NOLOCK)浅析 2014-08-30 11:58 by 潇湘隐者, 58264 阅读, 33 评论, 收藏, 编辑 概念介绍 开发人员喜欢在SQL脚本

    SQL Server 中WITH (NOLOCK)浅析 概念介绍 开发人员喜欢在SQL脚本中使用WITH(NOLOCK), WITH(NOLOCK)其实是表提示(table_hint)中的一种.它等同 ...

  7. 汽车引擎布局概念介绍(前置/中置/后置引擎的由来)

    汽车引擎布局概念介绍(前置/中置/后置引擎的由来) 为什么汽车有前置,中置,后置几种引擎布局?相信很多人会说:因为某某牌的车就是那样的.引擎一般都是车体最重而且最核心的部分,引擎在车架的位置决定着汽车 ...

  8. kafka中Topic、Partition、Groups、Brokers概念辨析

    kafka消息队列有两种消费模式,分别是点对点模式和订阅/发布模式.具体比较可以参考Kafka基础–消息队列与消费模式. 下图是一个点对点的Kafka结构示意图,其中有以下几个部分: producer ...

  9. java中batch基础_spring batch (一) 常见的基本的概念介绍

    SpringBatch的基本概念介绍 内容来自<Spring Batch 批处理框架>,作者:刘相. 一.配置文件 在项目中使用spring batch 需要在配置文件中声明: 事务管理器 ...

最新文章

  1. iOS--MD5加密封装
  2. React和Jquery比较
  3. 原生Android也能做Web开发了
  4. Citrix XenServer XenCenter 警报
  5. 从windows server的文件服务到分布式文件服务(十)
  6. HDU 4777 Rabbit Kingdom 树状数组
  7. java基础之设计模式
  8. 存储如何让文件小一点_如何使用Redis接管文件存储
  9. 快速排序算法_大佬的快速排序算法,果然不一样
  10. MATLAB常用正则表达式记录
  11. web前端期末大作业 基于HTML+CSS家乡主题毕业设计源码
  12. 稻盛和夫经典著作----《心》读后感
  13. 计算机组成原理_在线作业1,电子科大《计算机组成原理》在线作业1
  14. andriod 连接数据库(MySQL)
  15. 初级软件测试工程师工资(薪资待遇)一般是多少?
  16. 音游手台中--EC11编码器的控制[2]
  17. TFN OTDR光时域反射仪F1/F1K 手持式高精度光纤光缆断点检测仪
  18. 关于RecyclerView 兼顾setHasStableIds与Item动画问题
  19. vht160什么意思_华硕AX89X与AX200终于有160MHz了,WIFI6与WIFI5的速度对比测试-路由器交流...
  20. Protobuf—简介,优缺点

热门文章

  1. 蓝桥杯 让我怎能过大年 Java
  2. 二十四孝子,感天动地
  3. 如何提升设计的审美能力,从这6方面告诉你
  4. make 编译常用命令
  5. 常规onerror 的使用 和 vue 里面的onerror使用
  6. 不用化妆让你成漂亮女人
  7. [转]我最喜欢的情歌■■ 停留在心中的第二道彩虹
  8. vs mysql连接字符串_vs 数据库连接字符串
  9. iOS-图片处理 by GPUImage 滤镜
  10. html5 仪表盘 效果,html5动效系列十四:jQuery仪表盘指示器动画插件 6种仪表样式...