我第一次使用带有kafka的Node,使用kafka-node。使用消息需要调用外部API,甚至可能需要一秒钟来响应。我希望克服消费者突然失败的问题,如果消费者失败了,另一个将消费它的消费者将会接收消费者,这将得到同样的信息,即其工作尚未完成。
我正在使用kafka 0.10并尝试使用ConsumerGroup。
我想过在选项中设置autoCommit: false
,并且只在其工作完成后才提交消息(正如我之前用一些Java代码做过的那样)。
但是,我似乎无法确定只有在完成后才能正确提交消息。我该怎么做?
我担心的另一个问题是,由于回调,似乎在上一条消息完成之前正在读取下一条消息。而且我担心如果消息x + 2在消息x + 1之前完成,则偏移量将设置为x + 2,因此如果失败,x + 1将永远不会被重新执行。
这基本上是我到目前为止所做的:
var options = {
host: connectionString,
groupId: consumerGroupName,
id: clientId,
autoCommit: false
};
var kafka = require("kafka-node");
var ConsumerGroup = kafka.ConsumerGroup;
var consumerGroup = new ConsumerGroup(options, topic);
consumerGroup.on('connect', function() {
console.log("Consuming Kafka %s, topic=%s", JSON.stringify(options), topic);
});
consumerGroup.on('message', function(message) {
console.log('%s read msg Topic="%s" Partition=%s Offset=%d', this.client.clientId, message.topic, message.partition, message.offset);
console.log(message.value);
doSomeStuff(function() {
// HOW TO COMMIT????
consumerGroup.commit(function(err, data) {
console.log("------ Message done and committed ------");
});
});
});
consumerGroup.on('error', function(err) {
console.log("Error in consumer: " + err);
close();
});
process.once('SIGINT', function () {
close();
});
var close = function() {
// SHOULD SEND 'TRUE' TO CLOSE ???
consumerGroup.close(true, function(error) {
if (error) {
console.log("Consuming closed with error", error);
} else {
console.log("Consuming closed");
}
});
};
答案 0 :(得分:0)
您可以在这里做的一件事就是为您处理的每条消息都设置一个重试机制。
你可以在这个帖子上查阅我的答案: https://stackoverflow.com/a/44328233/2439404
我使用kafka-consumer
使用来自Kafka的消息,使用async/cargo
将它们一起批处理并将它们放在async/queue
(内存中队列)中。队列将工作函数作为我传递async/retryable
的争论。
对于您的问题,您可以使用retryable对邮件进行处理。 https://caolan.github.io/async/docs.html#retryable
这可以解决您的问题。