准备事件中的kafka-node未被触发

时间:2017-06-01 10:36:41

标签: javascript node.js apache-kafka

我为Kafka客户端和生产者创建了单例类,只创建了一个对象。 我需要多次发布相同的主题,而无需创建新的客户端和生产者实例。 我发现producer.on(' ready',fn(){})没有使用相同的客户端和生产者实例触发,只有在我有新的客户端和生产者对象时才第一次触发。

示例代码:

Singleton类:

const kafka = require('kafka-node');
const logger = require('./../../../../applogger');
const kafkaConfig = require('./../../../../config/config');

function ConnectionProvider() {
    let kafkaConnection = undefined;
    let client = undefined;

    this.getConnection = () => {

        if (!this.kafkaConnection) {
            logger.info("Creating new kafka connection ------------------------------------- ");
            this.client = new kafka.Client(kafkaConfig.ZOOKPER_HOST);
            this.kafkaConnection = new kafka.Producer(this.client);
        }
        return this.kafkaConnection;
    };
    this.getClient = () => {
        if (!this.client) {
            logger.info("Creating new kafka Client ------------------------------------- ");
            this.client = new kafka.Client(kafkaConfig.ZOOKPER_HOST);
        }
        return this.client;

    }
    process.on('SIGINT', function() {
        logger.info("Going to terminate kafka connection...!");
        process.exit(0);
    });
}
module.exports = exports = new ConnectionProvider;

主题发布方法:

const kafkaClient = require('./../core/kafkaConnection');

    const publishToKafka = function(dataPayload, callback) {
        logger.debug('Publishing to topic ', topicName, ' with data: ', dataPayload);
        let producer = kafkaClient.getConnection();

        producer.on('ready', function() {
            let payloads = dataPayload;
            producer.send(payloads, function(err, data) {
                if (err) {
                    logger.error(
                        'Error in publishing message to messaging pipeline ', err
                    );
                    callback(err, null);
                    return;
                }

                logger.debug('Published message to messaging pipeline topic ', topicName, ' with result: ', data);

                callback(null, data);
                return;
            });
        });

        producer.on('error', function(err) {
            logger.error(
                'Error in publishing message to messaging pipeline ', err
            );
            producer.close();
        });

    };

DataPayload是: 让dataPayload = [{topic:someTopic,message:someMessage}]

我需要多次调用PublishToKafka方法,但是只想创建一个kafka客户端和生产者实例。 但是生产者不会发布主题,因为在使用客户端和生产者的同一对象时,producer.on(' ready',function(){})没有被触发。

提前致谢。

1 个答案:

答案 0 :(得分:0)

我通过在每次调用后关闭kafka生成器和客户端实例来解决这个问题,因为我需要多次向kafka生成器发布,但默认情况下kafka zookeeper只允许60个最大连接(如果需要,我们可以增加连接值) 。这就是为什么为单个kafka实例创建单例类的原因。

但是在创建kafka的单个实例之后,它的producer.on('ready')事件将不会被触发,因为第二次我们使用了已经处于就绪状态的kafka生成器的同一个对象。所以我们每次都需要新的生产者实例进行发布。

const publishToKafka = function(topicName, dataPayload, callback) {
    logger.debug('Publishing to topic ', topicName, ' with data: ', dataPayload);
    let client = new kafka.Client(kakfaConfig.ZOOKPER_HOST);
    let producer = new kafka.Producer(client);


    producer.on('ready', function() {
        let payloads = dataPayload;
        producer.send(payloads, function(err, data) {
            if (err) {
                logger.error(
                    'Error in publishing message to messaging pipeline ', err
                );
                callback(err, null);
                return;
            }

            logger.debug('Published message to messaging pipeline topic ', topicName, ' with result: ', data);
            producer.close();
            client.close();
            callback(null, data);

            return;
        });
    });

    producer.on('error', function(err) {
        logger.error(
            'Error in publishing message to messaging pipeline ', err
        );
        producer.close();
    });

};

无需为单个对象创建单例类。