主题
本节描述了 Apache RocketMQ 中主题的定义、模型关系、内部属性和行为约束。本主题还提供了主题的版本兼容性信息和使用注意事项。
定义
主题在逻辑上是队列的集合;我们可以向其发布消息或从中接收消息。
主题提供以下优势
- 消息分类和消息隔离:当您基于 Apache RocketMQ 创建消息服务时,我们建议您使用不同的主题来管理不同业务类型的消息,以便进行隔离存储和订阅。
- 身份和权限管理:Apache RocketMQ 中的消息是匿名的。您可以使用主题对特定类别的消息执行身份和权限管理。
模型关系
下图显示了主题在 Apache RocketMQ 领域模型中的位置。
在 Apache RocketMQ 中,主题是一个顶层存储容器,其中定义了所有消息资源。主题是一个逻辑概念,而不是存储消息的实际单元。
一个主题包含一个或多个队列。消息存储和可伸缩性是基于队列实现的。主题的所有约束和属性设置都是基于主题中的队列实现的。
内部属性
主题名称
定义:主题的名称。主题名称标识主题,并且在集群中全局唯一。
值:主题名称在创建主题时由用户指定。
约束:请参阅参数限制。
队列
定义:存储消息的实际存储单元。一个主题包含一个或多个队列。有关更多信息,请参阅消息队列。
值:您可以在创建主题时指定队列的数量。Apache RocketMQ 会为主题分配指定数量的队列。
约束:一个主题必须包含至少一个队列。
消息类型
定义:为主题指定的消息类型。
值:在 Apache RocketMQ 中创建主题时,请为主题选择以下消息类型之一
约束:从 5.0 版本开始,Apache RocketMQ 支持强制验证消息类型,即每个主题只允许发送单一类型的消息。这可以更好地促进生产系统的操作和管理,避免混淆。但是,为了确保与 4.x 版本的向后兼容性,该验证功能默认是禁用的。
行为约束
强制消息类型验证
Apache RocketMQ 5.x 版本允许您为主题指定消息类型。通过这种方式,您可以在单独的主题中管理和处理指定类型的消息。Apache RocketMQ 会强制验证发送消息的类型以及消息发送到的主题的消息类型。如果消息类型验证失败,消息投递请求将被拒绝,并返回类型不匹配错误。以下验证规则适用
一致的消息类型。您要发送的消息必须使用与您要发送消息到的主题指定的消息类型相同的消息类型。
发送到主题的消息只能有一种类型。您要发送到主题的消息必须使用相同的消息类型。一个主题只能指定一种消息类型。
为了确保与 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 消息和普通消息。
消息相关性:使用单独的主题存储不直接相关的消息。例如,为淘宝交易消息和盒马物流消息创建两个主题,它们不相关。如果消息直接相关,则可以使用相同的主题。例如,您可以为淘宝男装和女装品类产生的订单消息创建一个主题。如果业务量或子模块需要更细粒度的主题,您也可以为可归类到一个主题的消息使用不同的主题。
消息量和及时性:使用不同的主题处理在消息量或及时性方面存在差异的消息。例如,不要将少量时间敏感消息的业务和生成数万亿消息的业务使用同一个主题。这可以防止时间敏感消息等待太长时间才能被消费。
正确主题规划示例:在电子商务场景中,您可以使用一个主题用于订单相关消息(如订单创建、支付和取消),一个主题用于物流消息,以及另一个主题用于积分相关消息。
不正确主题规划示例
粒度过粗:导致隔离性差。这不利于独立的运维和故障处理。这种不正确主题规划实践的一个例子是对所有交易消息和物流消息使用相同的主题。
粒度过细:消耗大量主题资源并增加系统负载。这种不正确主题规划实践的一个例子是为每个用户生成的消息使用单独的主题。
使用主题发送和接收相同类型的消息
基于主题的业务隔离是 Apache RocketMQ 的设计原则。我们建议您对使用不同业务逻辑的消息使用不同的主题。一个特定的主题必须发送或接收相同类型的消息。
避免主题的自动化管理
Apache RocketMQ 中的主题是顶层资源和容器,提供独立的权限管理、可观测性指标收集和监控功能。创建和管理主题需要系统资源。建议您仅在需要时才在生产环境中添加、删除、修改或查询主题。
尽管 Apache RocketMQ 提供了自动创建主题的功能,但我们建议您仅在测试环境中使用此功能。如果在生产环境中使用此功能,可能会生成大量不必要的主题。这会阻碍主题管理并消耗额外的系统资源。