PHP kafka消息隊列的使用
1.kafka安裝
kafka下載地址https://mirror.bit.edu.cn/apache/kafka/,這裏我下載的是最新版本2.5.0,這裏演示的是kafka單機單分區的情況:
cd /opt/
wget https://mirror.bit.edu.cn/apache/kafka/2.5.0/kafka_2.12-2.5.0.tgz
tar -zxvf kafka_2.12-2.5.0.tgz
mv kafka_2.12-2.5.0 kafka
cd kafka
# 編輯配置文件中的數據路徑即可,這裏只是演示單機單分區的情況
vim config/server.properties
log.dir=/opt/data_kafka
#保存退出
配置就可以了,下面啓動kafka,kafka是依賴zookeeper,所以需要先啓動自帶的zookeeper,再啓動kafka:
#啓動zookeeper -deamon表示後臺啓動
bin/zookeeper-server-start.sh -daemon config/zookeeper.properties
#啓動kafka -deamon表示後臺啓動
bin/kafka-server-start.sh -daemon config/server.properties
注意:啓動參數-daemon表示後臺啓動,啓動失敗是沒有任何信息的
測試kafka是否安裝以及啓動成功:
#創建topic
##--partitions 分區數
##--replication-factor 副本數
##--topic 主題名稱
bin/kafka-topics.sh --create --zookeeper localhost:2181 --partitions 1 --replication-factor 1 --topic test1
#測試生產/消費
##生產
bin/kafka-console-producer.sh --topic test1 --broker-list localhost:9092
##消費 --from-beginning表示從頭開始拉取消息
bin/kafka-console-consumer.sh --topic test1 --bootstrap-server localhost:9092 --from-beginning
#其他命令:
#查看主題列表
bin/kafka-topics.sh --list --zookeeper localhost:2181
#刪除主題
bin/kafka-topics.sh --delete --zookeeper localhost:2181 --topic test_name_1
#查看主題詳細信息
bin/kafka-topics.sh --describe --zookeeper localhost --topic test1
2.安裝php-kafka拓展
cd /opt/
#安裝librdkafka 庫
git clone https://github.com/edenhill/librdkafka.git
cd librdkafka
./configure
make
make install
#安裝php-rdkafka 擴展
git clone https://github.com/arnaud-lb/php-rdkafka.git
cd php-rdkafka
phpize
./configure --with-php-config=/usr/local/php/bin/php-config
make
make install
vim /usr/local/php/etc/php.ini
#加入這行
extension=rdkafka.so
重啓php-fpm
service php-fpm restart
檢查是否安裝成功:
php -m
#看到rdkafka表示安裝成功
3.PHP kafka的使用
生產者Mkafka類:
<?php
class Mkafka{
private $kafka;
private $broker_list = 'localhost:9092';
private $topic_list = array();
function __construct() {
$this->kafka = new RdKafka\Producer();
$this->kafka->addBrokers($this->broker_list);
}
public function getTopicByType($type = 0) {
$topic_obj;
$topic_key;
switch ($type) {
case 0:
$topic_key = 'user_visit';
if(empty($this->topic_list[$topic_key])) {
$this->topic_list[$topic_key] = $this->kafka->newTopic($topic_key);
}
$topic_obj = $this->topic_list[$topic_key];
break;
}
return $topic_obj;
}
/*
* 創建消息
* type 類型 0:用戶訪問記錄
*/
public function createMessage($type, $data = array()) {
$data = json_encode($data);
$topic_obj = $this->getTopicByType($type);
$topic_obj->produce(0, RD_KAFKA_MSG_F_BLOCK, $data);
$this->kafka->poll(0);
$result = $this->kafka->flush(10000);
return RD_KAFKA_RESP_ERR_NO_ERROR !== $result ? false : true;
}
}
調用生產者:
$kafka = new \Mkafka();
$result = $kafka->createMessage(0, array('name' => 'fdl'));
這時可以命令行打開消費者查看是否能消費新增的消息:
bin/kafka-console-consumer.sh --topic user_visit --bootstrap-server localhost:9092 --from-beginning
看到消息表示成功:
消費者代碼:
<?php
class MkafkaConsumer{
private $kafka;
private $config;
private $broker_list = 'localhost';
private $is_stop;
/*
* 初始化
* type 類型 0:用戶訪問
*/
function __construct($type) {
$group_id;
$topic;
switch ($type) {
case 0:
$group_id = 'user_visit_consumer';
$topic = 'user_visit';
break;
default:
throwErr('type err');
break;
}
$this->config = new RdKafka\Conf();
$this->config->set('group.id', $group_id);
$this->config->set('metadata.broker.list', $this->broker_list);
$this->kafka = new RdKafka\KafkaConsumer($this->config);
$this->kafka->subscribe([$topic]);
}
/*
* 消費消息
*/
public function consumeMessage() {
$this->is_stop = false;
while ($this->is_stop == false) {
$message = $this->kafka->consume(120*1000);
switch ($message->err) {
case RD_KAFKA_RESP_ERR_NO_ERROR:
echo 'success.';
var_dump($message);
echo '=======<br>';
break;
case RD_KAFKA_RESP_ERR__PARTITION_EOF:
echo "No more messages; will wait for more<br>";
break;
case RD_KAFKA_RESP_ERR__TIMED_OUT:
echo "Timed out<br>";
break;
default:
echo 'err.' . $message->errstr() . ' == ' . $message->err;
break;
}
if($this->is_stop == true) return true;
}
}
/* 停止消費 */
public function stopConsumeFromKafka() {
$this->is_stop = true;
}
}
總結:網上很多文章都是丟數據的,composer也有kafka的庫但是已經不能使用,最好的解決辦法還是參考官方文檔:
https://arnaud.le-blanc.net/php-rdkafka-doc/phpdoc/book.rdkafka.html