Laravel中Kafka的使用详解


Posted in PHP onMarch 24, 2021

本文并没有kafka的安装教程,本文是针对已经安装kafka及其配置好kafka的php拓展并且使用laravel框架进行开发项目,配置一个可供laravel框架使用的生产及消费者类.

以下代码修改自本站的YII框架关于kafka类的代码,经过测试使用在本人的项目中,可正常运行,larvael版本:5.6 代码放置larvael框架位置:app/Tools/Kafka.php

<?php
namespace App\Tools;
  
use Illuminate\Config\Repository;
  
use Illuminate\Support\Facades\DB;
use Monolog\Logger;
use Monolog\Handler\StreamHandler;
  
use Illuminate\Http\Request;
  
class Kafka
{
  public $broker_list = '127.0.0.1';//配置kafka,可以用逗号隔开多个kafka
  public $topic = 'test';//管道名称
  public $partition = 0;
  
  protected $producer = null;
  protected $consumer = null;
  
  public function __construct()
  {
    if (empty($this->broker_list)) {
      throw new InvalidConfigException("broker not config");
    }
    $rk = new \RdKafka\Producer();
    if (empty($rk)) {
      throw new InvalidConfigException("producer error");
    }
    $rk->setLogLevel(LOG_DEBUG);
    if (!$rk->addBrokers($this->broker_list)) {
      throw new InvalidConfigException("producer error");
    }
    $this->producer = $rk;
  }
  
  /**
   * 生产者
   * @param array $messages
   * @return mixed
   */
  public function send($messages = [],$topic)
  {
    $topic = $this->producer->newTopic($topic);
    return $topic->produce(RD_KAFKA_PARTITION_UA, $this->partition, json_encode($messages));
  }
  
  /**
   * 消费者
   */
  public function consumer($object, $callback){
    $conf = new \RdKafka\Conf();
    $conf->set('group.id', 0);
    $conf->set('metadata.broker.list', $this->broker_list);
  
    $topicConf = new \RdKafka\TopicConf();
    $topicConf->set('auto.offset.reset', 'smallest');
  
    $conf->setDefaultTopicConf($topicConf);
  
    $consumer = new \RdKafka\KafkaConsumer($conf);
  
    $consumer->subscribe([$this->topic]);
  
    echo "waiting for messages.....\n";
    while(true) {
      $message = $consumer->consume(120*1000);
      switch ($message->err) {
        case RD_KAFKA_RESP_ERR_NO_ERROR:
          echo "message payload....";
          $object->$callback($message->payload);
          break;
      }
      sleep(1);
    }
  }
}
?>

在控制器中如何使用:

首先再头部导入这个类:use App\Tools\Kafka;

下面是使用生产者实例:

public function test(){
  
   $topic = 'tool';//输入使用管道名称
   $data['shop_id'] = 58;
   $data['bar_code']=586;
   $data['goods_num'] = 1;
   $data['goods_unit'] = '个';
  
$Kafka = new Kafka();
$Error_Msg = $Kafka->send($data,$topic);//传入数组会自动转换json
var_dump($Error_Msg);
  
  
  }

下面是消费者实例,消费者我这里使用了的是php脚本进行的操作:

<?php
  
$conf = new RdKafka\Conf();
  
$conf->set('group.id', 'myConsumerGroup');
  
$rk = new RdKafka\Consumer($conf);
$rk->addBrokers("localhost: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("tool", $topicConf);//读取的管道
  
// Start consuming partition 0
$topic->consumeStart(0, RD_KAFKA_OFFSET_STORED);
  
while (true) {
  $message = $topic->consume(0, 120*10000);
  switch ($message->err) {
    case RD_KAFKA_RESP_ERR_NO_ERROR:
    //没有错误打印信息
      $message = json_decode(json_encode($message),true);
      $data = json_decode($message['payload'],true);
      var_dump($data);
      break;
    case RD_KAFKA_RESP_ERR__PARTITION_EOF:
      echo "等待接收信息\n";
      break;
    case RD_KAFKA_RESP_ERR__TIMED_OUT:
      echo "超时\n";
      break;
    default:
      throw new \Exception($message->errstr(), $message->err);
      break;
  }
 sleep(1);
}
  
?>
PHP 相关文章推荐
利用static实现表格的颜色隔行显示
Oct 09 PHP
Ajax PHP分页演示
Jan 02 PHP
基于OpenCV的PHP图像人脸识别技术
Oct 11 PHP
PHP中数组合并的两种方法及区别介绍
Sep 14 PHP
浅析PHP的静态成员函数效率更高的原因
Jun 13 PHP
从零开始学YII2框架(三)扩展插件yii2-gird
Aug 20 PHP
php提示Warning:mysql_fetch_array() expects的解决方法
Dec 16 PHP
PHP实现通过正则表达式替换回调的内容标签
Jun 15 PHP
ThinkPHP框架实现的MySQL数据库备份功能示例
May 24 PHP
Yii框架自定义数据库操作组件示例
Nov 11 PHP
PHP单元测试配置与使用方法详解
Dec 27 PHP
Laravel 自动转换长整型雪花 ID 为字符串的实现
Oct 27 PHP
thinkphp5 redis缓存新增方法实例讲解
php优化查询foreach代码实例讲解
Mar 24 #PHP
PHP引擎php.ini参数优化深入讲解
Mar 24 #PHP
PHP使用Redis队列执行定时任务实例讲解
Mar 24 #PHP
YII2 全局异常处理深入讲解
Laravel的加密解密与哈希实例讲解
Mar 24 #PHP
laravel使用redis队列实例讲解
You might like
php实现根据url自动生成缩略图的方法
2014/09/23 PHP
php无限极分类递归排序实现方法
2014/11/11 PHP
php显示指定目录下子目录的方法
2015/03/20 PHP
CodeIgniter配置之SESSION用法实例分析
2016/01/19 PHP
PHP哈希表实现算法原理解析
2020/12/11 PHP
JS获取父节点方法
2009/08/20 Javascript
JavaScript ( (__ = !$ + $)[+$] + ({} + $)[_/_] +({} + $)[_/_] )
2011/02/25 Javascript
javascript提取URL的搜索字符串中的参数(自定义函数实现)
2013/01/22 Javascript
nodejs实现遍历文件夹并统计文件大小
2015/05/28 NodeJs
jQuery获取页面元素绝对与相对位置的方法
2015/06/10 Javascript
jQuery编程中的一些核心方法简介
2015/08/14 Javascript
原生js实现图片轮播特效
2015/12/18 Javascript
JavaScript Canvas绘制圆形时钟效果
2020/08/20 Javascript
JS路由跳转的简单实现代码
2017/09/21 Javascript
vue.js input框之间赋值方法
2018/08/24 Javascript
你可能不知道的CORS跨域资源共享
2019/03/13 Javascript
关于JavaScript 数组你应该知道的事情(推荐)
2019/04/10 Javascript
[02:11]完美世界DOTA2联赛10月28日赛事精彩集锦:来吧展示实力强劲
2020/10/29 DOTA
编写Python脚本来获取mp3文件tag信息的教程
2015/05/04 Python
python获取指定路径下所有指定后缀文件的方法
2015/05/26 Python
Python列表list内建函数用法实例分析【insert、remove、index、pop等】
2017/07/24 Python
python判断文件夹内是否存在指定后缀文件的实例
2019/06/10 Python
pytorch中的自定义数据处理详解
2020/01/06 Python
pytorch实现对输入超过三通道的数据进行训练
2020/01/15 Python
tensorflow实现在函数中用tf.Print输出中间值
2020/01/21 Python
你可能不知道的Python 技巧小结
2020/01/29 Python
无惧面试,带你搞懂python 装饰器
2020/08/17 Python
pycharm 代码自动补全的实现方法(图文)
2020/09/18 Python
Python+unittest+DDT实现数据驱动测试
2020/11/30 Python
综治宣传月活动总结
2014/04/28 职场文书
小学师德师风整改措施
2014/10/27 职场文书
小学教研工作总结2015
2015/05/13 职场文书
张思德观后感
2015/06/09 职场文书
redis 查看所有的key方式
2021/05/07 Redis
解决xampp安装后Apache无法启动
2022/03/21 Servers
浅析JavaScript中的变量提升
2022/06/01 Javascript