php rdkafka操作kafka消息队列——k8s从入门到高并发系列教程(十七)

 ads:

关注以下公众号查看更多文章

安装kafka

通过docker

安装zookeeper

docker run -d --name zookeeper -p 2181:2181 -t wurstmeister/zookeeper

安装kafka

docker run  -d --name kafka -p 9092:9092 \
-e KAFKA_BROKER_ID=0 \
-e KAFKA_MESSAGE_MAX_BYTES=20000000 \
-e KAFKA_ZOOKEEPER_CONNECT=192.168.50.131:2181 \
-e KAFKA_ADVERTISED_LISTENERS=PLAINTEXT://192.168.50.131:9092 \
-e KAFKA_LISTENERS=PLAINTEXT://0.0.0.0:9092 \
-e KAFKA_LOG_RETENTION_HOURS=1 \
-e KAFKA_LOG_RETENTION_BYTES=10737418240 \
-e KAFKA_MAX_REQUEST_SIZE=20582912 \
-e KAFKA_REPLICA_FETCH_MAX_BYTES=20582912 \
-e KAFKA_FETCH_MESSAGE_MAX_BYTES=20485760 \
-t wurstmeister/kafka

通过k8s

增加bitnami repo仓库

helm repo add bitnami https://charts.bitnami.com/bitnami

安装zookeeper

helm install zookeeper bitnami/zookeeper \
  --set replicaCount=1 \
  --set auth.enabled=false \
  --set allowAnonymousLogin=true \
  -n rubyruby

可以看到如下的输出信息

** Please be patient while the chart is being deployed **

ZooKeeper can be accessed via port 2181 on the following DNS name from within your cluster:

zookeeper.rubyruby.svc.cluster.local

To connect to your ZooKeeper server run the following commands:

export POD_NAME=$(kubectl get pods --namespace rubyruby -l "app.kubernetes.io/name=zookeeper,app.kubernetes.io/instance=zookeeper,app.kubernetes.io/component=zookeeper" -o jsonpath="{.items[0].metadata.name}")
kubectl exec -it $POD_NAME -- zkCli.sh

To connect to your ZooKeeper server from outside the cluster execute the following commands:

kubectl port-forward --namespace rubyruby svc/zookeeper 2181:2181 &
zkCli.sh 127.0.0.1:2181

安装kafka

helm install kafka bitnami/kafka \
  --set zookeeper.enabled=false \
  --set replicaCount=1 \
  --set externalZookeeper.servers=zookeeper \
  -n rubyruby

输出信息如下 

** Please be patient while the chart is being deployed **

Kafka can be accessed by consumers via port 9092 on the following DNS name from within your cluster:

    kafka.rubyruby.svc.cluster.local

Each Kafka broker can be accessed by producers via port 9092 on the following DNS name(s) from within your cluster:

    kafka-0.kafka-headless.rubyruby.svc.cluster.local:9092

To create a pod that you can use as a Kafka client run the following commands:

    kubectl run kafka-client --restart='Never' --image docker.io/bitnami/kafka:3.3.1-debian-11-r1 --namespace rubyruby --command -- sleep infinity
    kubectl exec --tty -i kafka-client --namespace rubyruby -- bash

    PRODUCER:
        kafka-console-producer.sh \

            --broker-list kafka-0.kafka-headless.rubyruby.svc.cluster.local:9092 \
            --topic test

    CONSUMER:
        kafka-console-consumer.sh \

            --bootstrap-server kafka.rubyruby.svc.cluster.local:9092 \
            --topic test \
            --from-beginning

 php生产者消费者使用代码

<?php

$conf = new \RdKafka\Conf();
//rdkakfa的连接入口
$conf->set("metadata.broker.list", "kafka.rubyruby.svc.cluster.local:9092");

$topicConf = new \RdKafka\TopicConf();
//topic关闭自动提交
$topicConf->set('auto.commit.enable', 0);
$topicConf->set('auto.commit.interval.ms', 1000);
//从最近消息开始消费
$topicConf->set('auto.offset.reset', 'latest');

//kafka topic
$conf->setDefaultTopicConf($topicConf);

//rdkafka 消息
$rdKafkaMessage = new \RdKafka\Message();
//设置rdkafka消息topic
$rdKafkaMessage->topic_name = 'ruby1';
$headers = [
  'event' => 'live.broadcast.send.msg',
  'message_id' => md5(microtime(true) . uniqid('msg', true))
  ];
$payloads = [
  'uid' => "10000001",
  'roomid' => "10000002",
  'app' => 'rubyruby',
  'msg' => "hello world",
  'happened_at' => time(),
  ];
$payload['headers'] = $headers;
$payload['payload'] = $payloads;
//rdkafka消息负载内容
$rdKafkaMessage->payload = json_encode($payload);
$rdKafkaMessage->timestamp = time();
//消息key
$rdKafkaMessage->key = md5(microtime(true) . uniqid('key', true));

//生产者
$producer = new \RdKafka\Producer($conf);
//拿到topic
$topic = $producer->newTopic($rdKafkaMessage->topic_name);
//topic产生消息
$topic->producev(RD_KAFKA_PARTITION_UA, 0, json_encode($payload), $rdKafkaMessage->key, $headers);
//拿产生消息的结果
$result = $producer->flush(1000);
if (RD_KAFKA_RESP_ERR_NO_ERROR === $result) {
  echo "send success";
}

//rdkafka的消费组
$conf->set("group.id", "ruby-live");
//消费者重定分区
$conf->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);
    }
});
//kafka消费者对象
$consumer = new \RdKafka\KafkaConsumer($conf);
//自动安排分区
$consumer->subscribe([$rdKafkaMessage->topic_name]);
//主动设置分区
// $consumer->assign([
// new \RdKafka\TopicPartition("zzy8", 0),
// new \RdKafka\TopicPartition("zzy8", 1),
// ]);
//拿消息
$kafkaMessage = $consumer->consume(1000);
echo $kafkaMessage->err . PHP_EOL;
if($kafkaMessage->err == RD_KAFKA_RESP_ERR_NO_ERROR){
  print_r(json_decode($rdKafkaMessage->payload, true));
}else if($kafkaMessage->err == RD_KAFKA_RESP_ERR__TIMED_OUT){
  echo "连接超时";
}
//提交确认消息
try {
    $consumer->commitAsync($kafkaMessage);
    // $consumer->commit($kafkaMessage);
} catch (Exception $e) {
    throw new MessageAcknowledgeException($message, 'commit kafka message failed', $e);
}
//结束消息监听
$consumer->unsubscribe();

 相关链接

手把手教你部署nginx+php

php和nginx镜像合并 && 代码打包到镜像

nginx-php镜像安装常用软件

yaf && yar微服务/hprose微服务 镜像初始化

常用开发工具:php_codesniffer代码规范检查&修复、phpstan语法检查、phpunit单元测试

.gitlab-ci.yaml自动镜像打包&&互联网企业规范化上线流程(上)

kustomize/kubectl自动镜像部署&&互联网企业规范化上线流程(下)

apisix网关、JMeter压测  

prometheus/grafana监控数据收集与展示

k8s容器网络性能调优

supervisor进程管理

安装opcache和apcu

APM性能监测工具skywalking

链路跟踪工具zipkin

phpfpm和nginx配置

php整合apollo配置中心

php rdkafka操作kafka消息队列

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
你好!要在 PHP 中消费 Kafka 消息,你可以使用 rdkafka 扩展。以下是一个简单的示例代码,演示如何使用 rdkafka 消费 Kafka 消息: ```php <?php $conf = new RdKafka\Conf(); $conf->set('group.id', 'your-consumer-group-id'); $consumer = new RdKafka\KafkaConsumer($conf); $consumer->subscribe(['your-topic']); while (true) { $message = $consumer->consume(1000); // 等待一秒钟来获取消息 switch ($message->err) { case RD_KAFKA_RESP_ERR_NO_ERROR: // 成功接收到消息 echo $message->payload . PHP_EOL; break; case RD_KAFKA_RESP_ERR__PARTITION_EOF: // 所有分区上的消息已被消费完毕,等待更多消息 break; case RD_KAFKA_RESP_ERR__TIMED_OUT: // 等待超时 break; default: // 其他错误 echo '错误:' . $message->errstr() . PHP_EOL; break; } } ?> ``` 在上面的示例中,我们首先创建了一个 KafkaConsumer 对象,并设置了消费者组的 ID。然后通过调用 `subscribe` 方法订阅了要消费的主题。接下来,我们使用一个无限循环来不断尝试获取消息,并根据返回的错误代码进行相应的处理。 对于成功接收到的消息,你可以在 `echo` 语句中执行你的自定义逻辑。当所有分区上的消息都被消费完毕时,`RD_KAFKA_RESP_ERR__PARTITION_EOF` 错误代码会被触发,你可以根据需要进行处理。而 `RD_KAFKA_RESP_ERR__TIMED_OUT` 错误代码表示等待超时。 请注意,你需要先安装并启用 rdkafka 扩展,以便在 PHP 中使用它。你可以从 pecl 或源代码进行安装。希望这可以帮助到你!如果有任何问题,请随时问我。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

fanghailiang2016

扔个包子砸我一下吧~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值