使用Apache Kafka和NodeJS读取特定消息

时间:2016-04-28 16:34:50

标签: node.js apache-kafka

我想用NodeJS和Kafka构建一个API,它可以将偏移量和主题作为输入,并从偏移量开始输出前10个消息。我使用No-KafkaKafka-Node尝试了这种方法。

由它们提供的消费者API允许消费来自特定偏移量的消息。我想在阅读大约10条消息后停止使用这些消息。但是两个API调用都将继续获取消息,直到最后一条消息。我该怎么做呢?

这是我的已编辑的完整代码

var Kafka = require('no-kafka');
var express = require("express");
var app = express();

var producer = new Kafka.Producer();
producer.init().then(function() {
  console.log("Producer Ready");
});

var consumer = new Kafka.SimpleConsumer();
consumer.init().then(function() {
  console.log("Consumer Ready");
});

app.get('/produce/:topic/:msg', function(req, res) {
  producer.send({
    topic: req.params.topic,
    partition: 0,
    message: {
      value: req.params.msg
    }
  });
  res.send("Added: " + req.params.msg + " to topic: " + req.params.topic);
});

app.get('/consume/:topic/:off', function(req, res) {
  console.log("Request for topic: " + req.params.topic + " Offset: " + req.params.off);
  consumer.subscribe(req.params.topic, 0, {
    offset: req.params.off,
    maxBytes: 1000
  }, function(messageSet, topic, partition) {
    var msg = "";
    var size = messageSet.length;
    //console.log(messageSet);
    messageSet.some(function(m) {
      msg += m.message.value.toString('utf8') + " ";
      if (parseInt(m.offset, 10) > parseInt(req.params.off, 10) + 10) {
        return true;
      }
    });
    res.send("Thank you " + size + "  " + req.params.off + "  " + msg);
  });
});

app.listen(process.env.PORT);

对此方面的任何回应表示赞赏。

2 个答案:

答案 0 :(得分:0)

由于种种原因,你无法突然停止卡夫卡的消费。首先,Kafka消费者,无论是JavaScript还是其他东西,都不会一次阅读消息 - 他们会获取批量消息。我知道kafka-node似乎他们一次只有一个,因为每个消息都会收到EventEmitter个事件。但在引擎盖下,客户端会批量取出它们。

你可以做的最好的事情就是随时跟踪你的偏移,当你超出范围时你只想忽略它们,然后取消主题或关闭消费者以停止听。

分区肯定会变得更加棘手 - 您必须跟踪相对于所有分区的偏移量。我不会做同样的事情 - 我的典型用例是从一个时间点读取每个分区的当前偏移量。所以我没有优化我的分区读取,一旦它们达到它们的最后一个偏移量就会消失。我做addTopics并立即添加所有部分。另一方面,您可能需要一次添加一个分区 - 即对特定分区执行addTopic,在找到偏移量之前读取该分区,然后忽略消息并removeTopic开启分区。

我相信我玩弄了这个流程,你甚至可能需要为每个分区建立一个新的消费者,更不用说一个全新的客户了。

答案 1 :(得分:0)

我也在从事类似的项目。但是我要做的是,我设置了一个超时并达成协议,将您想要获取的偏移量和记录数传递给我。我将从您发送的偏移量中获取记录,但是我不能保证我们给您的记录数量。如果发生超时,它可能会获取较少的消息。但是,我们为您提供了上次读取记录的偏移量,以便您可以使用该偏移量再次调用。 (正如@David Griffin所说,问题是我们每次必须为每个分区创建一个新客户端。或者将数据存储在一个分区中,然后从该分区中获取数据。