#include "librdkafka/rdkafka.h"
static volatile sig_atomic_t run = 1;
static int wait_eof = 0;
static void stop(int sig) {
logger(const rd_kafka_t *rk, int level, const char *fac, const char *buf) {
gettimeofday(&tv, NULL);
fprintf(stderr, "%u.%03u RDKAFKA-%i-%s: %s: %s\n", (int)tv.tv_sec,
(int)(tv.tv_usec / 1000), level, fac,
rk ? rd_kafka_name(rk) : NULL, buf);
static void msg_consume(rd_kafka_message_t *rkmessage) {
if (rkmessage->err == RD_KAFKA_RESP_ERR__PARTITION_EOF) {
"%% Consumer reached end of %s [%" PRId32
"message queue at offset %" PRId64 "\n",
rd_kafka_topic_name(rkmessage->rkt),
rkmessage->partition, rkmessage->offset);
"%% Consume error for topic \"%s\" [%" PRId32
"offset %" PRId64 ": %s\n",
rd_kafka_topic_name(rkmessage->rkt),
rkmessage->partition, rkmessage->offset,
rd_kafka_message_errstr(rkmessage));
if (rkmessage->err == RD_KAFKA_RESP_ERR__UNKNOWN_PARTITION ||
rkmessage->err == RD_KAFKA_RESP_ERR__UNKNOWN_TOPIC)
if (rkmessage->key_len) {
printf("Key: %.*s\n", (int)rkmessage->key_len,
(char *)rkmessage->key);
printf("%.*s\n", (int)rkmessage->len,
(char *)rkmessage->payload);
print_partition_list(FILE *fp,
const rd_kafka_topic_partition_list_t *partitions) {
for (i = 0; i < partitions->cnt; i++) {
fprintf(fp, "%s %s [%" PRId32 "] offset %" PRId64,
i > 0 ? "," : "", partitions->elems[i].topic,
partitions->elems[i].partition,
partitions->elems[i].offset);
static void rebalance_cb (rd_kafka_t *rk,
rd_kafka_resp_err_t err,
rd_kafka_topic_partition_list_t *partitions,
fprintf(stderr, "%% Consumer group rebalanced: ");
case RD_KAFKA_RESP_ERR__ASSIGN_PARTITIONS:
fprintf(stderr, "assigned:\n");
print_partition_list(stderr, partitions);
rd_kafka_assign(rk, partitions);
wait_eof += partitions->cnt;
case RD_KAFKA_RESP_ERR__REVOKE_PARTITIONS:
fprintf(stderr, "revoked:\n");
print_partition_list(stderr, partitions);
rd_kafka_assign(rk, NULL);
fprintf(stderr, "failed: %s\n",
rd_kafka_assign(rk, NULL);
static void sig_usr1(int sig) {
rd_kafka_dump(stdout, rk);
int main(int argc, char **argv) {
char *mechanisms = NULL;
int partition = RD_KAFKA_PARTITION_UA;
rd_kafka_topic_partition_list_t *topics;
rd_kafka_resp_err_t err;
conf = rd_kafka_conf_new();
rd_kafka_conf_set_log_cb(conf, logger);
snprintf(tmp, sizeof(tmp), "%i", SIGIO);
rd_kafka_conf_set(conf, "internal.termination.signal", tmp, NULL, 0);
while ((opt = getopt(argc, argv, "h:t:b:u:p:g:m:e:d")) != -1) {
if (rd_kafka_conf_set(conf, "debug", optarg, errstr,
"%% Debug configuration failed: "
" -t <topic> 必填,需要生产的主题,可以从kafka主题页获取\n"
" -b <brokers> 必填,kafka实例的接入点,可以从实例详情页获取\n"
" -g <group> 必填, kafka消费组,当消费组不存在时,客户端会自动创建消费组\n"
" -u <user> 选填,使用SASL接入点时必填,可以从用户管理页面获取用户名称\n"
" -p <password> 选填,使用SASL接入点时必填,需要user对应的密码\n"
" -m <mechanisms> 选填, 使用SASL接入点时必填,加密类型,取值为PLAIN|SCRAM-SHA-256,可以从用户管理页面查询\n"
signal(SIGUSR1, sig_usr1);
rd_kafka_conf_set(conf, "bootstrap.servers", brokers, errstr,
sizeof(errstr)) != RD_KAFKA_CONF_OK) {
fprintf(stderr, "%% %s\n", errstr);
if (rd_kafka_conf_set(conf, "group.id", group_id,
errstr, sizeof(errstr)) !=
fprintf(stderr, "%% %s\n", errstr);
rd_kafka_conf_set_rebalance_cb(conf, rebalance_cb);
rd_kafka_conf_set(conf, "enable.partition.eof", "true", NULL,0);
if (rd_kafka_conf_set(conf, "auto.offset.reset", "earliest",
errstr, sizeof(errstr)) !=
fprintf(stderr, "%% %s\n", errstr);
if (mechanisms != NULL) {
if (rd_kafka_conf_set(conf, "security.protocol", "sasl_ssl", errstr, sizeof(errstr)) != RD_KAFKA_CONF_OK ||
rd_kafka_conf_set(conf, "ssl.endpoint.identification.algorithm", "none", errstr, sizeof(errstr)) != RD_KAFKA_CONF_OK ||
rd_kafka_conf_set(conf, "sasl.mechanisms", mechanisms, errstr, sizeof(errstr)) != RD_KAFKA_CONF_OK ||
rd_kafka_conf_set(conf, "sasl.username", user, errstr, sizeof(errstr)) != RD_KAFKA_CONF_OK ||
rd_kafka_conf_set(conf, "sasl.password", password, errstr, sizeof(errstr)) != RD_KAFKA_CONF_OK) {
fprintf(stderr, "%% %s\n", errstr);
if (!(rk = rd_kafka_new(RD_KAFKA_CONSUMER, conf, errstr,
"%% Failed to create new consumer: %s\n",
rd_kafka_poll_set_consumer(rk);
topics = rd_kafka_topic_partition_list_new(1);
rd_kafka_topic_partition_list_add(topics, topic, partition);
if ((err = rd_kafka_subscribe(rk, topics))) {
fprintf(stderr, "%% Failed to start consuming topics: %s\n", rd_kafka_err2str(err));
rd_kafka_message_t *rkmessage;
rkmessage = rd_kafka_consumer_poll(rk, 1000);
rd_kafka_message_destroy(rkmessage);
err = rd_kafka_consumer_close(rk);
fprintf(stderr, "%% Failed to close consumer: %s\n",
fprintf(stderr, "%% Consumer closed\n");
rd_kafka_topic_partition_list_destroy(topics);
while (run-- > 0 && rd_kafka_wait_destroyed(1000) == -1)
printf("Waiting for librdkafka to decommission\n");
rd_kafka_dump(stdout, rk);