使用RocketMQ的小细节(上)
Posted 冯先生的笔记
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用RocketMQ的小细节(上)相关的知识,希望对你有一定的参考价值。
消息过滤
说到消息过滤,就不得不说到 tag。没错,就是我们之前在专业术语中提到过的 tag。也称为消息标签,用来标记 Topic 下的不同用途的消息。
在 RocketMQ 中消费者是可以按照 Tag 对消息进行过滤。举个电商交易场景的例子,用户下完订单之后,在后台会产生一系列的消息,比如说订单消息、支付消息和物流消息。假设这些消息都发送到 Topic 为 Trade 中,同时用 tag 为 order 来标记订单消息,用 tag 为 pay 来标记支付消息,用 tag 为 logistics 来标记物流消息。需要支付消息的支付系统(相当于一个 consumer)订阅 Trade 中 tag 为 pay 的消息,此时,broker 则只会把 tag 为 pay 的消息投递给支付系统。而如果是一个实时计算系统,它可能需要接收所有和交易相关的消息,那么只要它订阅 Trade 中 tag 为 order、pay、logistics 的消息,broker 就会把带有这些 tag 的消息投递给实时计算系统。
对于消息分类,我们可以选择创建多个 Topic 来区分,也可以选择在同一个 Topic 下创建多个 tag 来区分。这两种方式都是可行的,但是一般情况下,不同的 Topic 之间的消息是没有什么必然联系的,使用 tag 来区分同一个 Topic 下相互关联的消息则更加合适一些。
订阅关系一致性
讲完了消息过滤,我们接着讲讲什么是订阅关系一致性呢?其实在讲 RocketMQ 消费模式的时候提到过,除了使用同一个 group name,订阅的 tag 也必须是一样的,只有符合这两个条件的 consumer 实例才能组成 consumer 集群。这里所说的其实就是订阅关系一致性。在 RocketMQ 中,订阅关系由 Topic和 Tag 组成,因此要保证订阅关系一致性,就必须同时保证这两点:
订阅的 Topic 必须一致
订阅的 Topic 中的 tag 必须一致
保证订阅关系一致性是非常重要的,一旦订阅关系不一致,消息消费的逻辑就会混乱,甚至导致消息丢失,这对于大部分业务场景来说都是不允许的,甚至是致命的。在实际使用中,切记同一个消费者集群内的所有消费者实例务必要保证订阅关系的一致性。
图 1
备注:图中 “*” 代表订阅该Topic下所有的 tag。
我们用具体的例子来解释一下,如图 1 所示,消费者集群中有 3 个 consumer 实例,分别为 C1、C2、C3,各自订阅的 topic 和 tag 各不相同。首先 C1 和 C2 都订阅 TopicA,满足了订阅关系一致性的第一点,但是 C1 订阅的是 TopicA 的 Tag1,而 C2 订阅的是 TopicA 的 Tag2,不满足订阅关系一致性的第二点,所以 C1、C2 不满足订阅关系一致性。而 C3 订阅的 Topic 和 Tag 都与 C1 和 C2不一样,同样也不满足订阅关系一致性。
图 2
备注:图中 “||” 用来连接不用的 tag,表示与的意思。
在图 2 中,消费者集群中有 3 个 consumer 实例,分别为 C1、C2、C3,都是订阅 TopicA 下的 Tag1 和 Tag2,满足了订阅关系一致性的两点要求,所以满足了订阅关系一致性。
图 3
如图 3 所示,一个 consumer 也可以订阅多个 Topic,同时也必须保证该 consumer 集群里的多个消费者实例的订阅关系一致性,才不会造成不必要的麻烦。
总结
在实际使用中,消息过滤可以帮助我们只消费我们所需要的消息,这是在broker端就帮我们处理好的,大大减少了在 consumer 端的消息过滤处理,一方面减少了代码量,另一方面更减少了不必要消息的网络传输消耗。
订阅消息一致性则保证了同一个消费者集群中 consumer 实例的正常运行,避免消息逻辑的混乱和消息的丢失。所以在实际使用中,在 producer 端要做好消息的分类,便于 consumer 可以使用 tag 进行消息的准确订阅,而在 consumer 端,则要保证订阅关系一致性。
以上是关于使用RocketMQ的小细节(上)的主要内容,如果未能解决你的问题,请参考以下文章