跳至主要内容
版本: 5.0

主题

本节描述 Apache RocketMQ 中主题的定义、模型关系、内部属性和行为约束。本主题还提供主题的版本兼容性信息和使用注意事项。

定义

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

主题提供以下优势

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

模型关系

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

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

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

内部属性

主题名称

  • 定义:主题的名称。主题名称标识主题,在集群中是全局唯一的。

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

  • 约束:请参阅 参数限制

队列

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

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

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

消息类型

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

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

    • 普通:普通消息。普通消息不需要特殊语义,也不与其他普通消息相关联。

    • FIFO:FIFO 消息。Apache RocketMQ 使用消息组来确定指定消息集的顺序。消息按发送顺序进行传递。

    • 延迟:延迟消息。您可以指定延迟,使消息仅在延迟时间过后才对消费者可用,而不是在生产时立即传递消息。

    • 事务:事务消息。Apache RocketMQ 支持分布式事务消息,并确保数据库更新和消息调用的事务一致性。

  • 约束:从 5.0 版本开始,Apache RocketMQ 支持强制执行消息类型验证,即每个主题只允许发送单一类型的消息。这可以更好地促进生产系统的操作和管理,并避免混淆。但是,为了确保与 4.x 版本的向后兼容性,验证功能默认情况下是启用的。

行为约束

强制消息类型验证

Apache RocketMQ 5.x 版本允许您为主题指定消息类型。这样,您可以在单独的主题中管理和处理指定类型的消息。Apache RocketMQ 会强制验证发送的消息类型和发送消息的主题的消息类型。如果消息类型验证失败,消息传递请求将被拒绝,并返回类型不匹配错误。以下验证规则适用

  • 一致的消息类型。您要发送的消息必须使用与您要发送消息的主题指定的相同消息类型。

  • 只允许发送一种类型的消息到主题。您要发送到主题的消息必须使用相同的消息类型。主题只能指定一种消息类型。

info

为了确保与 4.x 版本的向后兼容性,上述验证功能默认情况下是禁用的。建议使用服务器参数“enableTopicMessageTypeCheck”启用验证。

常见使用错误示例

  • 发送与主题消息类型不匹配的消息例如,发送到使用 FIFO 消息类型的主题的事务消息的请求将被拒绝,并返回类型不匹配错误。

  • 发送不同类型的消息到主题例如,发送普通消息和 FIFO 消息到使用普通消息类型的主题的请求将被拒绝,并返回类型不匹配错误。

版本兼容性

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

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

使用示例

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

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 中规划主题时,使用主题来处理为同一业务模块或业务方面的同一业务模块生成的的消息。在规划主题时,请注意以下因素

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

  • 消息关联:使用单独的主题来存储不直接关联的消息。例如,为淘宝交易消息和盒马鲜生物流消息创建两个主题,它们不相关。如果消息直接关联,您可以使用同一个主题。例如,您可以为淘宝男士服装类目和女士服装类目生成的订单消息创建一个主题。如果业务量或子模块需要更细粒度的主题,您也可以为可以归类到一个主题的消息使用不同的主题。

  • 消息量和时效性:使用不同的主题来处理在消息量或时效性方面存在差异的消息。例如,不要为一个生成少量时间敏感消息的业务和另一个生成数万亿消息的业务使用同一个主题。这可以防止时间敏感消息等待太长时间才能被消费。

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

主题规划错误示例

  • 粒度过粗:导致隔离性差。这不利于独立的 O\&M 和故障处理。这种错误的主题规划实践的一个例子是为所有交易消息和物流消息使用同一个主题。

  • 粒度过细:会消耗大量主题资源,增加系统负载。这种错误的主题规划实践的一个例子是为每个用户生成的的消息使用单独的主题。

使用主题来发送和接收相同类型的消息

基于主题的业务隔离是 Apache RocketMQ 的设计原则。建议您为使用不同业务逻辑的消息使用不同的主题。特定主题必须发送或接收相同类型的消息。

避免自动管理主题

Apache RocketMQ 中的主题是顶级资源和容器,提供独立的权限管理、可观测性指标收集和监控功能。创建和管理主题需要系统资源。建议您仅在生产环境中需要操作时才添加、删除、修改或查询主题。

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