我正在使用node-rdkafka使用node express开发Node JS。对于Kafka连接,我使用了Stream API。
我最初在两个不同的端点上设置了生产者和消费者。
对于生产者(kafkaRouter):
var express = require('express');
var router = express.Router();
var Kafka = require('node-rdkafka')
/* GET users listing. */
router.get('/', produceMessage);
// Our producer with its Kafka brokers
// This call returns a new writable stream to our topic 'topic-name'
var stream = Kafka.Producer.createWriteStream({
'metadata.broker.list': 'localhost:9092',
'dr_cb': true
}, {}, {
topic: 'test'
});
function produceMessage(req,res){
var queuedSuccess = stream.write(Buffer.from('Hey there!'));
if (queuedSuccess) {
console.log('We queued our message!');
} else {
// Note that this only tells us if the stream's queue is full,
// it does NOT tell us if the message got to Kafka! See below...
console.log('Too many messages in our queue already');
}
// NOTE: MAKE SURE TO LISTEN TO THIS IF YOU WANT THE STREAM TO BE DURABLE
// Otherwise, any error will bubble up as an uncaught exception.
stream.on('error', function (err) {
// Here's where we'll know if something went wrong sending to Kafka
console.error('Error in our kafka stream');
console.error(err);
})
return res.send("Hello Kafka!")
}
module.exports = router;
对于消费者,我将函数放在索引(indexRouter)中:
var express = require('express');
var router = express.Router();
var { KafkaConsumer } = require('node-rdkafka');
/* GET home page. */
router.get('/', getMessage);
const globalConfig = {
'client.id': 'kafka-mocha',
'group.id': 'kafka-mocha-grp',
'metadata.broker.list': 'localhost:9092'
};
var stream = KafkaConsumer.createReadStream(globalConfig, {}, {
topics: ['test']
});
function getMessage(req,res){
var result = '';
stream.on('data', function(message) {
console.log('Got message');
console.log(message.value.toString());
result = result + ' ' + message.value.toString()
});
stream.consumer.commit();
return res.send("Express Router");
}
module.exports = router;
然后我将它们添加到app.js
var express = require('express');
var app = express();
app.use('/', indexRouter);
app.use('/kafka', kafkaRouter);
我在这种方法上注意到的是,我只需要调用一次indexRouter,并且使用者将连续监听Queue,并且每次生产者推送一条消息时。尽管工作正常,但如果只需要调用一次,则将使用者放在路由器上是很尴尬的。所以我想我可以像这样直接将其放在app.js中:
const run = async () => {
const globalConfig = {
'client.id': 'kafka-mocha',
'group.id': 'kafka-mocha-grp',
'metadata.broker.list': 'localhost:9092'
};
var stream = KafkaConsumer.createReadStream(globalConfig, {}, {
topics: ['test']
});
var result = '';
stream.on('data', function(message) {
console.log('Got message');
console.log(message.value.toString());
result = result + ' ' + message.value.toString()
});
stream.consumer.commit();
}
run().catch(e => console.error(e));
我还尝试将其封装在静态方法中,然后调用。两种方法都给了我这个错误:
node-kafka-test@0.0.0 start /Users/workspace/node-kafka-test
> node ./bin/www
Error: KafkaConsumer is disconnected
at KafkaConsumer.commit