php rdkafka 扩展的使用

官方说明地址:https://arnaud-lb.github.io/php-rdkafka/phpdoc/book.rdkafka.html 里面说的很详细不再赘述,包含安装和demo。以下贴出自己的实战代码,以作备忘。

生产者代码:(短信、邮件推送到kafka)

setLogLevel(LOG_DEBUG);
$rk->addBrokers("127.0.0.1:9092");
$topic = $rk->newTopic("sms");
for ($i = 0; $i < 10; $i++) {
    $content = "第" . $i . "次报警";
    $message = ["mobile" => "18812345678", "content" => $content];
    $payload = json_encode($message);
    //指定向0号partition生产数据
    //$topic->produce(0, 0, $payload);
    //随机选择partition
    $topic->produce(RD_KAFKA_PARTITION_UA, 0, $payload);
    //if ($rk->getOutQLen() > 0) {
    //    $rk->poll(500);
    //} else {
        $rk->poll(0);
    //} 
}

低级消费者:(只从指定的partition消费)

set('group.id', 'sms-consumer-group');
$rk = new RdKafka\Consumer($conf);
$rk->addBrokers("127.0.0.1:9092");
$topicConf = new RdKafka\TopicConf();
$topicConf->set('auto.commit.interval.ms', 100);
$topicConf->set('offset.store.method', 'file');
$topicConf->set('offset.store.path', sys_get_temp_dir());
$topicConf->set('auto.offset.reset', 'smallest');
$topic = $rk->newTopic("sms", $topicConf);
$topic->consumeStart(0, RD_KAFKA_OFFSET_STORED);

while(true) {
    $message = $topic->consume(0, 5000);
    if ($message) {
        echo "读取到消息\n\r";
        var_dump($message);
        switch($message->err)
        {
            case RD_KAFKA_RESP_ERR_NO_ERROR:
                echo "读取消息成功:\n\r";
                var_dump($message->payload);
                break;
            case RD_KAFKA_RESP_ERR__PARTITION_EOF:
                echo "读取消息失败\n\r";
                break;
            case RD_KAFKA_RESP_ERR__TIMED_OUT:
                echo "请求超时\n\r";
                break;
            default:
                throw new \Exception($message->errstr(), $message->err);
            break;
        }
    } else {
        echo "未读取到消息\n\r";
    }
}

高级消费者:(动态自适应partition消费,也可以指定多个topic)

setRebalanceCb(function(RdKafka\KafkaConsumer $kafka, $err, array $partitions = null) {
    switch($err) {
        case RD_KAFKA_RESP_ERR__ASSIGN_PARTITIONS:
            $kafka->assign($partitions);
            break;
        case RD_KAFKA_RESP_ERR__REVOKE_PARTITIONS:
            $kafka->assign(NULL);
            break;
        default:
            throw new \Exception($err);
    }
});

$conf->set("group.id", "sms-consumer-group");
$conf->set("metadata.broker.list", "127.0.0.1:9092");
$topicConf = new RdKafka\TopicConf();
$topicConf->set("auto.offset.reset", "smallest");
$conf->setDefaultTopicConf($topicConf);
$consumer = new RdKafka\KafkaConsumer($conf);
$consumer->subscribe(["sms"]);
while(true) {
    $message = $consumer->consume(20000);
    switch($message->err) {
        case RD_KAFKA_RESP_ERR_NO_ERROR:
            echo "正确读取到数据\n\r";
            var_dump($message->payload);
            break;
        case RD_KAFKA_RESP_ERR__PARTITION_EOF:
            echo "没有读到数据\n\r";
            break;
        case RD_KAFKA_RESP_ERR__TIMED_OUT:
            echo "读取数据超时\n\r";
            break;
        default:
            throw new \Exception($message->errstr(), $message->err);
            break;
        }
}

 

你可能感兴趣的:(kafka,消息队列,消息队列)