跳转至主要内容
版本: 5.0

主题 (Topic)

本节介绍 Apache RocketMQ 中主题(Topic)的定义、模型关系、内部属性和行为约束。此外,还提供了主题的版本兼容性信息及使用注意事项。

定义

主题在逻辑上是消息队列的集合;我们可以向其发布消息或从中接收消息。

主题具有以下优势:

  • 消息分类与消息隔离:当您基于 Apache RocketMQ 构建消息服务时,我们建议您使用不同的主题来管理不同业务类型的消息,以便实现隔离存储和订阅。
  • 身份与权限管理:Apache RocketMQ 中的消息是匿名的。您可以使用主题对特定类别的消息进行身份和权限管理。

模型关系

下图显示了主题在 Apache RocketMQ 领域模型中的位置。Topic

在 Apache RocketMQ 中,主题是定义所有消息资源的顶级存储容器。主题是一个逻辑概念,并非存储消息的实际单元。

一个主题包含一个或多个队列。消息的存储和可扩展性是基于队列实现的。关于主题的所有约束和属性设置均基于该主题内的队列来实现。

内部属性

主题名称

  • 定义:主题名称。主题名称用于标识主题,在整个集群中具有全局唯一性。

  • 值:主题名称由用户在创建主题时指定。

  • 约束:请参阅 参数限制

队列(Queues)

  • 定义:存储消息的实际存储单元。一个主题包含一个或多个队列。更多信息,请参阅 消息队列

  • 值:您可以在创建主题时指定队列数量。Apache RocketMQ 会为该主题分配指定数量的队列。

  • 约束:一个主题必须至少包含一个队列。

消息类型

  • 定义:为主题指定的消息类型。

  • 值:在 Apache RocketMQ 中创建主题时,请为主题选择以下消息类型之一:

    • 普通消息(Normal):普通消息。普通消息不需要特殊的语义,与其他普通消息之间没有关联。

    • 顺序消息(FIFO):顺序消息。Apache RocketMQ 使用消息组(Message Group)来确定一组特定消息的顺序。消息将按照发送顺序进行投递。

    • 延迟消息(Delay):延迟消息。您可以指定延迟时间,使消息在延迟过后才对消费者可见,而不是在生产时立即投递。

    • 事务消息(Transaction):事务消息。Apache RocketMQ 支持分布式事务消息,确保数据库更新与消息调用之间的事务一致性。

  • 约束:从 5.0 版本开始,Apache RocketMQ 支持强制验证消息类型,即每个主题仅允许发送单一类型的消息。这有助于更好地进行生产系统的运维管理并避免混淆。然而,为了确保与 4.x 版本的向后兼容性,该验证功能默认处于关闭状态。

行为约束

强制消息类型验证

Apache RocketMQ 5.x 版本允许您为主题指定消息类型。通过这种方式,您可以管理并处理特定类型的主题消息。Apache RocketMQ 会强制验证发送的消息类型是否与目标主题的消息类型一致。如果验证失败,消息发送请求将被拒绝,并返回类型不匹配错误。适用以下验证规则:

  • 消息类型一致性:您发送的消息必须与目标主题指定的消息类型保持一致。

  • 主题仅限单一消息类型:发送到同一主题的消息必须使用相同的消息类型。每个主题只能指定一种消息类型。

提示

为了确保与 4.x 版本的向后兼容性,上述验证功能默认处于禁用状态。建议通过服务端参数 "enableTopicMessageTypeCheck" 开启此验证功能。

常见使用错误示例

  • 向主题发送与类型不匹配的消息:例如,向一个定义为 FIFO 消息类型的主题发送事务消息,请求将被拒绝,并返回类型不匹配错误。

  • 向同一主题发送不同类型的消息:例如,向一个定义为普通消息类型的主题同时发送普通消息和顺序消息,请求将被拒绝,并返回类型不匹配错误。

版本兼容性

强制消息类型验证仅在 Apache RocketMQ 5.x 版本中可用。Apache RocketMQ 4.x 和 3.x 版本的 SDK 不支持此功能。如果您使用 4.x 或 3.x 版本,请确保消息类型的一致性。

我们建议您使用 Apache RocketMQ 5.x 版本。

使用示例

建议使用 mqadmin 工具在 Apache RocketMQ 5.0 中创建主题。但需要注意,必须将消息类型作为属性参数添加。以下是一个示例:

sh mqadmin updateTopic -n <nameserver_address> -t <topic_name> -c <cluster_name> -a +message.type=<message_type>

其中,message_type 参数可以根据消息类型设置为 Normal/FIFO/Delay/Transaction。如果未指定,则默认为 Normal 类型。

使用说明

根据业务需求规划主题

在规划 Apache RocketMQ 主题时,建议为相同业务模块或业务维度的消息使用同一个主题。规划主题时请考虑以下因素:

  • 消息类型:使用不同的主题存储不同类型的消息。例如,您可以创建两个主题分别存储顺序消息和普通消息。

  • 消息关联性:对于没有直接关联的消息,应使用独立的主题。例如,为淘宝交易消息和盒马物流消息创建两个独立的主题,因为它们互不相关。如果消息之间有直接关联,可以使用同一个主题。例如,您可以为淘宝男装类目和女装类目的订单消息创建一个主题。如果业务量或子模块需要更细粒度的控制,也可以针对可归类于同一主题的消息使用不同的主题。

  • 消息容量与时效性:对于容量或时效性要求不同的消息,应使用不同的主题。例如,不要将一个产生少量时效敏感消息的业务与另一个产生海量消息的业务混用同一个主题。这可以防止时效敏感的消息因等待消费而造成延迟。

正确的主题规划示例:在电商场景中,您可以为订单相关消息(如订单创建、支付、取消)使用一个主题,为物流消息使用一个主题,再为积分相关消息使用另一个主题。

错误的主题规划示例

  • 粒度过粗:会导致隔离性差,不利于独立运维和故障处理。例如,将所有交易消息和物流消息混用同一个主题属于错误的规划实践。

  • 粒度过细:会消耗大量主题资源并增加系统负载。例如,为每个用户的消息创建一个独立的主题属于错误的规划实践。

使用一个主题发送和接收同一类型的消息

基于主题的业务隔离是 Apache RocketMQ 的设计原则。我们建议您针对使用不同业务逻辑的消息使用不同的主题。一个特定的主题必须仅发送或接收同一种类型的消息。

避免自动化管理主题

Apache RocketMQ 中的主题是提供独立权限管理、可观测指标采集和监控能力的顶级资源与容器。创建和管理主题需要系统资源。我们建议仅在必要时在生产环境中增、删、改、查主题。

尽管 Apache RocketMQ 提供自动创建主题的功能,但我们建议仅在测试环境中使用。如果在生产环境中使用,可能会产生大量不必要的主题,这会妨碍主题管理并消耗额外的系统资源。