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 相关文章推荐
PHP 5.0 Pear安装方法
Dec 06 PHP
php中使用ExcelFileParser处理excel获得数据(可作批量导入到数据库使用)
Aug 21 PHP
php摘要生成函数(无乱码)
Feb 04 PHP
PHP中函数rand和mt_rand的区别比较
Dec 26 PHP
php实现的漂亮分页方法
Apr 17 PHP
php结合ACCESS的跨库查询功能
Jun 12 PHP
PHP实现发送邮件的方法(基于简单邮件发送类)
Dec 17 PHP
thinkPHP简单遍历数组方法分析
May 16 PHP
php+ajax登录跳转登录实现思路
Jul 31 PHP
Thinkphp开发--集成极光推送
Sep 15 PHP
PHP+ajax实现二级联动菜单功能示例
Aug 10 PHP
基于PHP实现解密或加密Cloudflar邮箱保护
Jun 24 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
上传文件先创建目录 再上传到目录里面去
2010/12/29 PHP
PHP写的加密函数,支持私人密钥(详细介绍)
2013/06/09 PHP
PHP中static关键字以及与self关键字的区别
2015/07/01 PHP
PHP框架Laravel插件Pagination实现自定义分页
2020/04/22 PHP
PHP 断点续传实例详解
2017/11/11 PHP
5 cool javascript apps
2007/03/24 Javascript
js Event对象的5种坐标
2011/09/12 Javascript
Chosen 基于jquery的选择框插件使用方法
2012/05/30 Javascript
window.location.href = window.location.href 跳转无反应 a超链接onclick事件写法
2013/08/21 Javascript
js获取事件源及触发该事件的对象
2013/10/24 Javascript
使用jquery中height()方法获取各种高度大全
2014/04/02 Javascript
javascritp添加url参数将参数加入到url中
2014/09/25 Javascript
jQuery满屏焦点图左右滚动特效代码分享
2015/09/07 Javascript
js如何实现淡入淡出效果
2020/11/18 Javascript
深入浅析JavaScript中with语句的理解
2016/05/12 Javascript
Bootstrap选项卡学习笔记分享
2017/02/13 Javascript
Bootstrap表格使用方法详解
2017/02/17 Javascript
原生js实现放大镜
2017/02/20 Javascript
javascript 实现文本使用省略号替代(超出固定高度的情况)
2017/02/21 Javascript
js学使用setTimeout实现轮循动画
2017/07/17 Javascript
vue富文本编辑器组件vue-quill-edit使用教程
2018/09/21 Javascript
JavaScript类的继承操作实例总结
2018/12/20 Javascript
微信小游戏之使用three.js 绘制一个旋转的三角形
2019/06/10 Javascript
JS 封装父页面子页面交互接口的实例代码
2019/06/25 Javascript
学习LayUI时自研的表单参数校验框架案例分析
2019/07/29 Javascript
javascript实现前端成语点击验证
2020/06/24 Javascript
python操作xml文件示例
2014/04/07 Python
python实现杨辉三角思路
2017/07/14 Python
对Pycharm创建py文件时自定义头部模板的方法详解
2019/02/12 Python
python3实现微型的web服务器
2019/09/03 Python
对Pytorch中Tensor的各种池化操作解析
2020/01/03 Python
css3动画事件—webkitAnimationEnd与计时器time事件
2013/01/31 HTML / CSS
致百米运动员广播稿
2014/01/29 职场文书
电工工作职责范本
2014/02/22 职场文书
公司市场专员岗位职责
2014/06/29 职场文书
理解深度学习之深度学习简介
2021/04/14 Python