Pulsar Subscriptions(消息订阅)

目录

1、Subscriptions 消息订阅

(1)Subscription types 订阅类型

(2)Subscription modes 订阅模式

2、Multi-topic subscriptions 多主题订阅


1、Subscriptions 消息订阅

        订阅是一个被命名的配置规则,该规则决定如何将消息传递给使用者。Pulsar 有四种可用的订阅类型:独占类型(exclusive)、共享类型(shared)、容错类型(failover)、共享 key 类型(key_shared)。这些类型的图示说明如下:

        发布订阅或者消息排队

        在 Pulsar 中,你可以灵活使用不同的订阅类型:

  • 如果想要在多个消费者之间实现传统的消息发布和订阅,可以为每个消费者都指定一个唯一的订阅名称。这种订阅类型称为独占(exclusive)订阅类型。
  • 如果想要在多个消费者之间实现消息队列,让多个消费者能够共享相同的订阅名称,那么可以使用共享(shared)、容错(failover)或者共享key(key_shared)等订阅类型来实现。
  • 如果想要同时实现这两种效果,可以将独占订阅类型与消费者的其他订阅类型结合使用。

(1)Subscription types 订阅类型

        如果一个订阅没有消费者,那么无法确定该订阅的类型。订阅的类型需要在消费者连接到该订阅时确定,该类型也可以根据消费者的不同配置在重启所有消费者后进行改变// 改变订阅类型需要重启所有的消费者

        独占订阅类型(Exclusive)

        在独占订阅类型中,仅允许一个消费者进行订阅。如果多个消费者连接到该订阅类型,除了允许其中一个消费者进行订阅外,其他消费者创建时将会发生错误。Exclusive 是默认的订阅类型

        在下图中,仅允许 Consumer A-0 消费消息。

        容错订阅类型(Failover)

        在容错订阅类型中,可以有多个消费者添加到同一个订阅。同时,会从多个消费者中会选择一个消费者作为主节点(master)来接收主题的消息。如果主节点断开连接,所有剩余的消息(未确认和后续生产的)都会被传递到队列中的下一个消费者进行消费。// 其实仍然只有一个消费者进行消费,其他消费者处于等待状态。

        对于分区主题,代理(broker)将按优先级和消费者名称的词典顺序对消费者进行排序。然后尝试将主题平均分配给具有最高优先级的消费者。

        对于非分区主题,代理(broker)将按照消费者订阅主题的顺序选择消费者。

        在下图中,Consumer-B-0 是主 Consumer,如果 Consumer-B-0 断开连接,Consumer-B-1 将是下一个接收消息的 Consumer。

        共享订阅类型(Shared)

        在共享订阅类型中,可以有多个消费者添加到同一个订阅。消息在消费者之间以循环分发的方式传递,任何给定的消息都只传递给一个消费者。当其中一个消费者断开连接时,所有发送给它但未确认的消息都将重新安排发送给其余的消费者。// 消息只会被消费一次

        在下图中,Consumer-C-1 和 Consumer-C-2 添加到了该类型的订阅,同时 Consumer-C-3 和其消费者也可以添加到此订阅。

        共享订阅类型有一些的限制,使用该类型时,请注意:

  • 不保证消息排序。
  • 不能对共享类型使用累积确认。

        共享key订阅类型(Key_Shared)

        在共享 key 订阅类型中,可以有多个消费者添加到同一个订阅。消息会根据 Key 在消费者之间进行分配,具有相同 Key 或相同排序 Key 的消息仅会传递给一个消费者。无论该消息被重新传递多少次,它都会传递给同一个消费者。当消费者进行连接或断开连接时,都会将导致已经存在的消费者消费消息的 key 的变更。

        请注意,当消费者使用 Key_Shared 订阅类型时,需要生产者禁用批处理或者只使用基于Key的批量处理。 Key_Shared 订阅类型必须使用基于 Key 的批处理(key-based batching)有两个原因:

  1. 代理(broker)根据消息的 Key 分发消息,但默认的批量处理方法可能无法将具有相同 Key 的消息打包到同一批量中。
  2. 另外,因为消费者而不是代理从批量中分派消息,因此批量中第一条消息的 Key 将被视为该批量中所有消息的 Key,从而导致消息传递错误。

        基于 Key 的批量处理需要解决上述问题。该批量处理方法需要确保生产者将具有相同 Key 的消息打包到同一批量中,没有 Key 的消息打包到另一个批量中(该批量没有 Key),当代理(broker)从此批量处理中调度消息时,它使用 NON_KEY 作为 Key。此外,每个消费者仅与一个 Key 关联,并且应该只接收这个 Key 的批量消息。默认情况下,您可以通过配置允许生产者发送的消息数来限制批量消息的大小。

        下面是在 Key_Shared 订阅类型下启用基于 Key 的批量处理的示例,客户端是你创建的 Pulsar 客户端:

Producer<byte[]> producer = client.newProducer()
        .topic("my-topic")
        .batcherBuilder(BatcherBuilder.KEY_BASED) // 启用批处理
        .create();

使用 Key_Shared 订阅类型时有一些限制,使用 Key_Shared 订阅类型时,请注意:

  • 需要为消息指定 Key 或排序 Key。
  • 不能对 Key_Shared 订阅类型使用累积确认

(2)Subscription modes 订阅模式

什么是订阅模式?

订阅模式是指记录消费位置的游标类型

  • 创建订阅时,将创建一个关联的游标来记录上次消费的位置
  • 当该订阅的消费者重新连接时,它可以继续从最后一次消费消息的地方开始消费。
Subscription modeDescriptionNote

Durable

持久的

The cursor is durable, which retains messages and persists the current position.

// 游标是持久的,它保留消息并保持当前位置。
If a broker restarts from a failure, it can recover the cursor from the persistent storage (BookKeeper), so that messages can continue to be consumed from the last consumed position.

// 如果代理从故障中重新启动,它可以从持久性存储(BookKeeper)中恢复游标,以便可以从上次消费的位置继续消费消息。

Durable is the default subscription mode.

// 默认持久的

NonDurable

非持久的

The cursor is non-durable.
Once a broker stops, the cursor is lost and can never be recovered, so that messages can not continue to be consumed from the last consumed position.

// 一旦代理停止,游标将丢失并且永远无法恢复,因此消息无法从上次消费的位置继续消费。

Reader’s subscription mode is NonDurable in nature and it does not prevent data in a topic from being deleted. Reader’s subscription mode can not be changed.

// 读者的订阅模式本质上是不持久的,它不会阻止删除主题中的数据。读者的订阅模式无法更。

        订阅可以有一个或多个消费者。消费者消费主题的消息时,必须指定订阅的名称。持久订阅和非持久订阅可以具有相同的名称,它们彼此独立。如果消费者指定了之前不存在的订阅,则会自动创建该订阅

什么时候使用订阅模式?

        默认情况下,非持久订阅模式主题的消息会被标记为已删除。如果想要阻止消息被标记为已删除,可以为此主题创建持久订阅模式。在这种情况下,只有已确认的消息才会被标记为已删除。有关更多信息,请参阅消息保留和过期

如何使用订阅模式?

        创建消费者后,消费者的默认订阅模式是持久的。通过更改建消费者的配置,可以将订阅模式更改为非持久模式。

// 持久模式
Consumer<byte[]> consumer = pulsarClient.newConsumer()
        .topic("my-topic")
        .subscriptionName("my-sub")
        .subscriptionMode(SubscriptionMode.Durable) // 持久模式
        .subscribe();
        
// 非持久模式
Consumer<byte[]> consumer = pulsarClient.newConsumer()
        .topic("my-topic")
        .subscriptionName("my-sub")
        .subscriptionMode(SubscriptionMode.NonDurable)
        .subscribe();

        有关如何创建、检查或删除持久订阅,请参阅订阅管理

2、Multi-topic subscriptions 多主题订阅

        当消费者通过订阅附加到 Pulsar 主题时,默认情况下,它只会订阅一个特定的主题,例如 persistent : // public / default / my-topic,然而,从 Pulsar 1.23.0-Cubating 版本开始,Pulsar 消费者可以同时订阅多个主题。你可以通过下边两种方式定义主题列表:

  1. 基于正则表达式(regex),例如:persistent : // public / default / finance-.*
  2. 通过明确的定义主题列表

通过 regex 订阅多个主题时,所有主题必须位于同一命名空间中。

// pulsar 可以跨命名空间订阅主题吗?

        订阅多个主题时,Pulsar 客户端会自动的调用 Pulsar API 去发现与正则表达式匹配的主题,然后订阅所有主题。如果其中有主题不存在,一旦这些主题被创建,消费者会自动订阅这些主题。

跨多主题不保证消息顺序

        当生产者将消息发送到单个主题时,所有消息都能保证以相同的顺序从该主题读取。但是,跨多个主题的情况下这些顺序并不能保证。因此,当生产者向多个主题发送消息时,消息在这些主题中的读取顺序不能保证与生产者发送的顺序一致。

        以下是 Java 的多主题订阅示例:


import java.util.regex.Pattern;

import org.apache.pulsar.client.api.Consumer;
import org.apache.pulsar.client.api.PulsarClient;

PulsarClient pulsarClient = // Instantiate Pulsar client object

// Subscribe to all topics in a namespace
Pattern allTopicsInNamespace = Pattern.compile("persistent://public/default/.*");
Consumer<byte[]> allTopicsConsumer = pulsarClient.newConsumer()
                .topicsPattern(allTopicsInNamespace) // 订阅命名空间下所有主题
                .subscriptionName("subscription-1")
                .subscribe();

// Subscribe to a subsets of topics in a namespace, based on regex
Pattern someTopicsInNamespace = Pattern.compile("persistent://public/default/foo.*");
Consumer<byte[]> someTopicsConsumer = pulsarClient.newConsumer()
                .topicsPattern(someTopicsInNamespace) // 订阅命名空间下部分主题
                .subscriptionName("subscription-1")
                .subscribe();

点击回到首页

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值