简体   繁体   English

使用 pulsar 消息侦听器进行多线程处理

[英]Multithreading with pulsar message listeners

I'm fairly new to java message listeners and apache pulsar .我对java message listenersapache pulsar相当apache pulsar Assume that I've maintained a listener like so,假设我一直保持这样的听众,

private MessageListener<byte[]> generateListener() {
        MessageListener<byte[]> listener = (consumer, respMsg) -> {
            String respM = new String(respMsg.getValue(), StandardCharsets.UTF_8);
            logger.info(respM);
            consumer.acknowledgeAsync(respMsg);
        };
        return listener;
    }

And a Consumer instance like so,还有一个像这样的消费者实例,

Consumer<byte[]> c = consumerBuilder.messageListener(generateListener()).topic(topicName).subscriptionName("Consumer-" + i).subscribeAsync().get();

What I would like to know is how multiple incoming messages would be handled by this listener?我想知道的是此侦听器将如何处理多个传入消息? Will each message be handled in a seperate thread as in the case of JMS listeners?是否会像 JMS 侦听器那样在单独的线程中处理每条消息? If so, then how can I configure the number of threads to use - is it by using the ClientBuilder.listenerThreads() property?如果是这样,那么我如何配置要使用的线程数 - 是使用ClientBuilder.listenerThreads()属性吗?

Is there a need to maintain multiple listener objects respective to each consumer, when maintaining multiple consumers ie, something like this -在维护多个消费者时,是否需要为每个消费者维护多个侦听器对象,即类似这样的东西 -

consumerBuilder.clone().messageListener(generateListener()).topic(topicName).subscriptionName("Consumer-" + i).subscribeAsync() ? consumerBuilder.clone().messageListener(generateListener()).topic(topicName).subscriptionName("Consumer-" + i).subscribeAsync() ?

The ClientBuilder#listenerThreads method allows configuring the size of an internal thread-pool that will be shared and used across all Consumers or Readers that will be created from that client. ClientBuilder#listenerThreads方法允许配置内部线程池的大小,该线程池将在将从该客户端创建的所有ConsumersReaders之间共享和使用。

Pulsar Client will give you the guarantee that a MessageListener for a single consumer will always be invoked by the same thread, ie that the provided MessageListener don't need to be thread-safe. Pulsar Client 将向您保证单个消费者的MessageListener将始终由同一线程调用,即提供的MessageListener不需要是线程安全的。 So, YES it is prefered to use a dedicated MessageListener object per Consumer .因此,是的,每个Consumer使用专用的MessageListener对象。

Note that this also ensure ordering.请注意,这也确保了排序。

So basically, if you only use a single Consumer then you can keep the listenerThreads to 1 (that is the default).所以基本上,如果你只使用一个Consumer那么你可以将 listenerThreads 保持为1 (这是默认值)。

Here is a complete example that can used to observe the behaviour :这是一个完整的示例,可用于观察行为:

public class PulsarConsumerListenerExample {

    public static void main(String[] args) throws PulsarClientException {

        int numListenerThread = 2;

        PulsarClient client = PulsarClient
                .builder()
                .serviceUrl("pulsar://localhost:6650")
                .listenerThreads(numListenerThread)
                .build();

        final List<Consumer<?>> consumers = new ArrayList<>();
        for (int i = 0; i < numListenerThread; i++) {
            consumers.add(createConsumerWithLister(client, "my-topic", "my-subscription", "C" + i));
        }

        Runtime.getRuntime().addShutdownHook(new Thread(() -> {
            for (Consumer<?> consumer : consumers) {
                try {
                    consumer.close();
                } catch (PulsarClientException e) {
                    e.printStackTrace();
                }
            }
        }));
    }

    private static Consumer<String> createConsumerWithLister(final PulsarClient client,
                                                             final String topic,
                                                             final String subscription,
                                                             final String consumerName) throws PulsarClientException {
        return client.newConsumer(Schema.STRING)
            .topic(topic)
            .consumerName(consumerName)
            .subscriptionName(subscription)
            .subscriptionMode(SubscriptionMode.Durable)
            .subscriptionType(SubscriptionType.Failover)
            .subscriptionInitialPosition(SubscriptionInitialPosition.Earliest)
            .messageListener((MessageListener<String>) (consumer, msg) -> {
                System.out.printf(
                    "[%s/%s]Message received: key=%s, value=%s, topic=%s, id=%s%n",
                    consumerName,
                    Thread.currentThread().getName(),
                    msg.getKey(),
                    msg.getValue(),
                    msg.getTopicName(),
                    msg.getMessageId().toString());
                consumer.acknowledgeAsync(msg);
            })
            .subscribe();
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 带有事件监听器的Android多线程 - Android multithreading with event listeners 如何在 Pulsar 中按键获取消息 - How to get message by key in Pulsar Pulsar 消息总线:我们可以为每个主题配置消息保留吗? - Pulsar message bus: Can we configure message retention per topic? 消费者应用程序使用消息后,如何从主题队列中删除脉冲星消息? - how to remove the pulsar message from queue for a topic after message is consumed by a consumer application? 由于模式类型错误(JSON 而不是 AVRO),Pulsar 函数无法反序列化消息 - Pulsar function fails to deserialize message because of wrong schema type (JSON instead of AVRO) 消息监听器和 jmslistener 注解有什么区别 - Whats the difference between message listeners and jmslistener annotation Firebase:在我说之前,不要向所有听众发送消息 - Firebase: Don't send message to all the listeners until I say 具有相同GroupId的多个Kafka侦听器全部接收消息 - Multiple Kafka Listeners With Same GroupId All Receiving Message 单个数据存储的多个消息侦听器。 高效的设计 - Multiple message listeners to single data store. Efficient design 每个主题在集​​群中运行的每个侦听器仅消耗一次消息 - Consume message only once from Topic per listeners running in cluster
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM