kafka 消息队列 php-rdkafka扩展示例

4 篇文章 1 订阅

php版本为:7.2

# cd /var/www/html/

生产者,producer.php

<?php
$rk = new RdKafka\Producer();
$rk->setLogLevel(LOG_DEBUG); // 设置日志级别
$rk->addBrokers('127.0.0.1'); // 添加经纪人,就是ip地址

$topic = $rk->newTopic("test2"); // 新建主题

// 第一个参数:是分区。RD_KAFKA_PARTITION_UA代表未分配,并让librdkafka选择分区
// 第二个参数:是消息标志,必须为0
// 第三个参数:消息,如果不为NULL,它将被传递给主题分区程序
$topic->produce(RD_KAFKA_PARTITION_UA, 0, 'Message'); // 生成并发送单个消息

低级消费者,consumer.php
低级消费者就是:当你重启后消费过的消息队列还会存在,也就是说:低级消费者是用来处理可重复消费的数据的。

<?php
$rk = new RdKafka\Consumer();
$rk->setLogLevel(LOG_DEBUG); // 设置日志级别
$rk->addBrokers("127.0.0.1"); // 添加经纪人,就是ip地址

$topic = $rk->newTopic("test2"); // 这里的$rk和生产者是不同的类哦

// 第一个参数分区ID
// 第二个参数是开始消费的偏移量,有效值
$topic->consumeStart(0, RD_KAFKA_OFFSET_BEGINNING);

while (true) {
    // 第一个参数是要消耗的分区
    // 第二个参数是等待收到消息的最长时间,1000是一秒
    $msg = $topic->consume(0, 1000);
    if (@$msg->err) {
        echo $msg->errstr(), "\n"; // 输出错误
        break;
    } else {
        echo @$msg->payload, "\n"; // 输出消息
    }
}

测试

# cd /var/www/html/
# php consumer.php

新打开一个终端,运行生产者,发送消息

# php producer.php

在这里插入图片描述
每当生产者运行一次就会发送一条消息,消费者那边就会接收到这条消息并进行相应的处理。

然而,上面只是为了好理解,实际上我们用的时候是需要处理完队列的某一条数据后就使其出列。也就是不需让它再出现。

高级消费者
将低级消费者代码注释。

<?php
$conf = new RdKafka\Conf();

$conf->setRebalanceCb(function (RdKafka\KafkaConsumer $kafka, $err, array $partitions = null) {
    switch ($err) {
        case RD_KAFKA_RESP_ERR__ASSIGN_PARTITIONS:
            echo "Assign: ";
            var_dump($partitions);
            $kafka->assign($partitions);
            break;

        case RD_KAFKA_RESP_ERR__REVOKE_PARTITIONS:
            echo "Revoke: ";
            var_dump($partitions);
            $kafka->assign(NULL);
            break;

        default:
            throw new \Exception($err);
    }
});

$conf->set('group.id', 'myConsumerGroup');

$conf->set('metadata.broker.list', '127.0.0.1');

$topicConf = new RdKafka\TopicConf();

$topicConf->set('auto.offset.reset', 'smallest');

$conf->setDefaultTopicConf($topicConf);

$consumer = new RdKafka\KafkaConsumer($conf);

$consumer->subscribe(['test2']);

while (true) {
    $message = $consumer->consume(120*1000);
    switch ($message->err) {
        case RD_KAFKA_RESP_ERR_NO_ERROR:
            var_dump($message);
            break;
        case RD_KAFKA_RESP_ERR__PARTITION_EOF:
            echo "No more messages; will wait for more\n";
            break;
        case RD_KAFKA_RESP_ERR__TIMED_OUT:
            echo "Timed out\n";
            break;
        default:
            throw new \Exception($message->errstr(), $message->err);
            break;
    }
}

启动消费者

# php consumer.php

启动生产者

# php producer.php

查看消费者终端,出现了消息。

ctrl+c,重新启动消费者。

你会发现,之前消费过的就不会重新输出了。

但是现在有个问题,如果服务挂了未消费的数据会丢失吗?我们来试试看吧。

用php的sleep('3')来延时,放在while循环中。

启动消费者,然后运行十次生产者。把消费者ctrl+c。

在这里插入图片描述
重启前消费到3。

重启linux再启动kafka。
在这里插入图片描述
重启linux后,启动消费者,从4开始了。

php-rdkafka扩展函数手册

高级消费者set说明

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值