暂停高级卡夫卡消费者

时间:2016-05-06 11:42:09

标签: apache-kafka kafka-consumer-api

我在Kafka消费者之下,我想在某种情况下暂停,然后稍后恢复以消耗所有先前的消息。一个想法是使用共享标志,该标志可以由其他线程更新并在消费之前,即iterator.next().message()我检查标志的值。如果它真的不消耗其他消费消息。只是想检查我是否正在考虑正确的方向,或者是否有更好的方法。

class KafkaConsumer implements Runnable {
        KafkaStream<byte[], byte[]> topicStream;
        ConsumerConnector consumerConnectorObj;

        public KafkaConsumer(final KafkaStream<byte[], byte[]> topicStream,
                final ConsumerConnector consumerConnectorObj) {
            this.topicStream = topicStream;
            this.consumerConnectorObj = consumerConnectorObj;
        }

        @Override
        public void run() {
            if (topicStream != null) {
                ConsumerIterator<byte[], byte[]> iterator = topicStream.iterator();
                while (true) {
                        if (iterator != null) {
                            boolean nextFlag = true;
                            try {
                                iterator.hasNext();
                            } catch (ConsumerTimeoutException e) {
                                LOG.warn("Consumer timeout occured", e);
                                nextFlag = false;
                            }

                            if (nextFlag) {
                                byte[] msg = iterator.next().message();
                            }
                        }
                }
            }
        }
    }

1 个答案:

答案 0 :(得分:1)

通常你不需要通过手工制作的方式在线程之间进行同步,因为你很有可能弄错它。请看java.util.concurrent帮助者。在你的情况下,它可能是一个信号量。使用它的最简单方法是在处理消息之前获取信号量,之后将其交还并尝试在下一个循环中立即再次获取它。

我的预感是,这不是最好的方法。我宁愿打电话给availablePermits()并继续消费,而数字则更大。只有当它降到零时,尝试获取信号量。这将阻塞线程,直到另一个线程再次提供一个许可。这将取消阻止你的工作线程,并将其交给许可证,它应该立即返回,如上所述开始循环。

while (true) {
  if (semaphore.availablePermits()<=0) {
    semaphore.acquire(); // will block
    // eventually another thread increments the semaphore again
    // and we arrive here
    semaphore.release();
  }
  // keep processing messages
}

您可以在this question的答案中找到其他想法。