如何在librdkafka中使用KAFKA的生产者API和windows

时间:2017-06-10 18:58:47

标签: c++ apache-kafka producer

我正在尝试将客户端编写为生产者。 我按照示例创建了一个新的win32控制台项目。 除非我在程序结束时添加了getline()函数,否则我发现API对我不起作用。

如果我删除了getline(),那么produce(..)方法仍会返回成功的结果。 但是,我在kafka-console-consumer

的命令窗口中看不到任何响应

我有点困惑。是对的吗? 如何在不使用getline()的情况下发送消息? 有人知道吗?

我发现为什么它不起作用。 删除生成器对象似乎太快了 导致生产者无法向经纪人发送消息。

当我在Produ方法和删除生成器对象之间添加sleep 1000时, 制作人可以正确发送消息。

所以,问题是如何立即发送消息。 在销毁生产者对象之前,如何确保完全发送这些消息?

如何解决这个问题,实际上我不想在我的源代码中添加一些sleep()。

win10 + vs2015 + kafka_2.10-0.9.0.1 +动物园管理员-3.4.6 + librdkafka 请查看以下代码

    // kafka_test_win32_nomfc.cpp 
//

#include "stdafx.h"
#include <iostream>
#include "librdkafka/rdkafkacpp.h"


int static producer_1()
{
    std::string brokers = "127.0.0.1";
    std::string errstr;
    std::string topic_str = "linli";
    std::string mode;
    std::string debug;
    int32_t partition = RdKafka::Topic::PARTITION_UA;
    int64_t start_offset = RdKafka::Topic::OFFSET_BEGINNING;
    bool do_conf_dump = false;
    int opt;
    // MyHashPartitionerCb hash_partitioner;
    int use_ccb = 0;

    /*
    * Create configuration objects
    */
    RdKafka::Conf *conf = RdKafka::Conf::create(RdKafka::Conf::CONF_GLOBAL);
    RdKafka::Conf *tconf = RdKafka::Conf::create(RdKafka::Conf::CONF_TOPIC);

    conf->set("metadata.broker.list", brokers, errstr);

    RdKafka::Producer *producer = RdKafka::Producer::create(conf, errstr);
    if (!producer) {
        std::cerr << "Failed to create producer: " << errstr << std::endl;
        exit(1);
    }

    std::cout << "% Created producer " << producer->name() << std::endl;

    /*
    * Create topic handle.
    */
    RdKafka::Topic *topic = NULL;
    if (!topic_str.empty()) {
        topic = RdKafka::Topic::create(producer, topic_str, tconf, errstr);
        if (!topic) {
            std::cerr << "Failed to create topic: " << errstr << std::endl;
            exit(1);
        }
    }

    RdKafka::ErrorCode resp = producer->produce(topic, partition,
        RdKafka::Producer::RK_MSG_COPY /* Copy payload */,
        const_cast<char *>("hello worlf"), 11,
        NULL, NULL);

    delete topic;
    delete producer;
    return 0;
}


int static producer_2()
{
    std::string brokers = "127.0.0.1";
    std::string errstr;
    std::string topic_str = "linli";
    std::string mode;
    std::string debug;
    int32_t partition = RdKafka::Topic::PARTITION_UA;
    int64_t start_offset = RdKafka::Topic::OFFSET_BEGINNING;
    bool do_conf_dump = false;
    int opt;
    // MyHashPartitionerCb hash_partitioner;
    int use_ccb = 0;

    RdKafka::Conf *conf = RdKafka::Conf::create(RdKafka::Conf::CONF_GLOBAL);
    RdKafka::Conf *tconf = RdKafka::Conf::create(RdKafka::Conf::CONF_TOPIC);

    conf->set("metadata.broker.list", brokers, errstr);

    RdKafka::Producer *producer = RdKafka::Producer::create(conf, errstr);
    if (!producer) {
        std::cerr << "Failed to create producer: " << errstr << std::endl;
        exit(1);
    }

    std::cout << "% Created producer " << producer->name() << std::endl;

    RdKafka::ErrorCode resp = producer->produce(topic_str, partition,
        RdKafka::Producer::RK_MSG_COPY /* Copy payload */,
        (void *)"hi", 2,
        NULL, 0, 0, NULL);



    std::string errs(RdKafka::err2str(resp));
    std::cout << errs << std::endl;
    //producer->poll(0);


    delete producer;

    return 0;
}


int main()
{

    producer_2();

    return 0;
}

1 个答案:

答案 0 :(得分:6)

librdkafka produce()API(包括C和C ++)是异步的,您的消息最初只会在内部生成器队列中排队,并且只能在以后(参见class myLayout(FloatLayout): def eraser(self): self.canvas.clear() def _keyboard_on_key_down(self, keyboard, keycode, text, modifiers): self.canvas.clear() global i i = i + 1 initialy = 400-(stim_list[i]/2) xlab = Label(text='X', pos=(0, 350)) with self.canvas: self.add_widget(xlab) Color(1., 1, 1) Rectangle(pos=(initialx, initialy), size=(stimwidth, stim_list[i])) Clock.schedule_once(eraser(),3) 配置属性 - 默认1秒)进行组合将其他消息放入消息批处理(MessageSet)并从后台线程发送给代理。

您的程序调用{​​{1}},然后在后台生成器线程有机会将消息发送给代理之前很快退出,更不用说从代理接收确认。

要确保已发送所有未完成的消息,请在终止您的应用程序之前致电queue.buffering.max.ms

如果您的申请是长期存在的,您应定期致电produce(),以便为您已注册的任何投放回复提供服务。