PHP kafka消息队列的使用

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

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1,SDK简介 本SDK是基于ThinkPHP开发类库扩展,因此只能在ThinkPHP平台下使用(ThinkPHP版本要求2.0以上)。DEMO中用到了控制器分层,因此运行DEMO需使用ThinkPHP3.1.2版本。 2,目前支持的平台 目前可用登录平台为:腾讯QQ,腾讯微博,新浪微博,网易微博,人人网,360,豆瓣,Github,Google,MSN,点点,百度,开心网,搜狐。 3,包含的文件 ThinkSDK/ThinkOauth.class.php SDK基类,主要用于Oauth的认证,所有平台的SDK均需要继承此类 ThinkSDK/sdk/DiandianSDK.class.php (点点SDK) ThinkSDK/sdk/DoubanSDK.class.php (豆瓣SDK) ThinkSDK/sdk/GithubSDK.class.php (Github SDK) ThinkSDK/sdk/GoogleSDK.class.php (Google SDK) ThinkSDK/sdk/MsnSDK.class.php (MSN SDK) ThinkSDK/sdk/QqSDK.class.php (腾讯QQ SDK) ThinkSDK/sdk/RenrenSDK.class.php (人人网SDK) ThinkSDK/sdk/SinaSDK.class.php (新浪微博SDK) ThinkSDK/sdk/T163SDK.class.php (网易微博SDK) ThinkSDK/sdk/TencentSDK.class.php (腾讯微博SDK) ThinkSDK/sdk/X360SDK.class.php (360 SDK) ThinkSDK/sdk/BaiduSDK.class.php (百度SDK) ThinkSDK/sdk/KaixinSDK.class.php (开心网SDK) ThinkSDK/sdk/SohuSDK.class.php (搜狐SDK) 4,配置格式 SDK的配置格式如下(可参考DEMO中的配置) //将一下(TYPE)换成你对应的SDK类型 'THINK_SDK_(TYPE)' => array( 'APP_KEY' => '', //应用注册成功后分配的 APP ID 'APP_SECRET' => '', //应用注册成功后分配的KEY 'CALLBACK' => '', //注册应用填写的callback ) 5,接入登录方法 添加ThinkPHP扩展,将整个ThinkSDK目录放入到ThinkPHP的扩展目录下~Extend/Library/ORG/~。 添加SDK配置,按以上配置格式在项目配置中添加对应的SDK配置。(可参考DEMO中的配置文件) 跳转到授权页面,导入SDK基类import("ORG.ThinkSDK.ThinkOauth"),获取SDK实例$sdk=ThinkOauth::getInstance($type),跳转到授权页面redirect($sdk->getRequestCodeURL())。(可参考DEMO中的Index/login方法) 获取access_token,在授权成功的回调页面中,调用$sdk->getAccessToken($code, $extend)方法来获取access_token。(可参考DEMO中的Index/callback方法) 6,调用API方法 成功获取到access_token之后就可以调用相应平台的API了,调用方法比较简单,只需要调用$sdk->call($api, $param, $method)方法就可以了,其中:$api为接口名称,$param为接口参数(格式:name1=value1&name2=value2), $method为请求方法(GET或POST)。 例如: import("ORG.ThinkSDK.ThinkOauth"); //导入SDK基类 $qq = ThinkOauth::getInstance('qq', $token); //实例化腾讯QQ开放平台对象 $token 参数为授权成功后获取到的 $token $data = $qq->call('user/get_user_info'); //调用接口

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值