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的开发框架的现状和展望
Mar 16 PHP
PHP下10件你也许并不了解的事情
Sep 11 PHP
PHP下利用shell后台运行PHP脚本,并获取该脚本的Process ID的代码
Sep 19 PHP
PHP设计模式之装饰者模式
Feb 29 PHP
用php实现选择排序的解决方法
May 04 PHP
PHPMailer的主要功能特点和简单使用说明
Feb 17 PHP
php实现cookie加密的方法
Mar 10 PHP
php实现倒计时效果
Dec 19 PHP
PHP远程调试之XDEBUG
Dec 29 PHP
注意!PHP 7中不要做的10件事
Sep 18 PHP
使用PHPStorm+XDebug搭建单步调试环境
Nov 19 PHP
Laravel框架实现的使用smtp发送邮件功能示例
Mar 12 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 中的批处理的实现
2007/06/14 PHP
php下MYSQL limit的优化
2008/01/10 PHP
PHP在不同页面间传递Json数据示例代码
2013/06/08 PHP
php使用exec shell命令注入的方法讲解
2013/11/12 PHP
浅析php设计模式之数据对象映射模式
2016/03/03 PHP
如何打开php的gd2库
2017/02/09 PHP
关于php开启错误提示的总结
2019/09/24 PHP
jQuery对表单的操作代码集合
2011/04/06 Javascript
JS小功能(列表页面隔行变色)简单实现
2013/11/28 Javascript
JavaScript中数据结构与算法(五):经典KMP算法
2015/06/19 Javascript
jQuery限制图片大小的方法
2016/05/25 Javascript
JS代码实现根据时间变换页面背景效果
2016/06/16 Javascript
JS获取多维数组中相同键的值实现方法示例
2017/01/06 Javascript
jQuery修改DOM结构_动力节点Java学院整理
2017/07/05 jQuery
node.js实现的装饰者模式示例
2017/09/06 Javascript
使用Node.js实现ORM的一种思路详解(图文)
2017/10/24 Javascript
基于element-ui组件手动实现单选和上传功能
2018/12/06 Javascript
新手快速上手webpack4打包工具的使用详解
2019/01/28 Javascript
详解JS判断页面是在手机端还是在PC端打开的方法
2019/04/26 Javascript
layui数据表格跨行自动合并的例子
2019/09/02 Javascript
vuejs实现下拉框菜单选择
2020/10/23 Javascript
Element-ui 自带的两种远程搜索(模糊查询)用法讲解
2021/01/29 Javascript
[01:00:25]NB vs Secret 2018国际邀请赛小组赛BO1 B组加赛 8.19
2018/08/21 DOTA
[49:43]VG vs FNATIC 2019国际邀请赛小组赛 BO2 第一场 8.15
2019/08/17 DOTA
wxPython定时器wx.Timer简单应用实例
2015/06/03 Python
python中yaml配置文件模块的使用详解
2018/04/27 Python
python中itertools模块zip_longest函数详解
2018/06/12 Python
python3.6 tkinter实现屏保小程序
2019/07/30 Python
Python实现使用dir获取类的方法列表
2019/12/24 Python
Win下PyInstaller 安装和使用教程
2019/12/25 Python
Django调用百度AI接口实现人脸注册登录代码实例
2020/04/23 Python
ASP.NET Core中的配置详解
2021/02/05 Python
HTML5 本地存储之如果没有数据库究竟会怎样
2013/04/25 HTML / CSS
工程管理造价应届生求职信
2013/11/13 职场文书
行政助理的职责
2013/11/14 职场文书
2015年学校信息技术工作总结
2015/05/25 职场文书