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 数组基础知识小结
Aug 20 PHP
新手菜鸟必读:session与cookie的区别
Aug 22 PHP
PHP中使用匿名函数操作数据库的例子
Nov 17 PHP
php+xml结合Ajax实现点赞功能完整实例
Jan 30 PHP
php检索或者复制远程文件的方法
Mar 13 PHP
PHP记录搜索引擎蜘蛛访问网站足迹的方法
Apr 15 PHP
PHP YII框架开发小技巧之模型(models)中rules自定义验证规则
Nov 16 PHP
大家都应该掌握的PHP关联数组使用技巧
Dec 25 PHP
基于Swoole实现PHP与websocket聊天室
Aug 03 PHP
PHP批量修改文件名称的方法分析
Feb 27 PHP
php引用和拷贝的区别知识点总结
Sep 23 PHP
laravel框架中表单请求类型和CSRF防护实例分析
Nov 23 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面向对象的方法重载两种版本比较
2008/09/08 PHP
php 人员权限管理(RBAC)实例(推荐)
2017/05/24 PHP
Laravel给生产环境添加监听事件(SQL日志监听)
2017/06/19 PHP
php成功操作redis cluster集群的实例教程
2019/01/13 PHP
php7 list()、session及其他模块的修改实例分析
2020/05/25 PHP
一个加载js文件的小脚本
2007/06/28 Javascript
js 刷新页面的代码小结 推荐
2010/04/02 Javascript
javascript奇异的arguments分析
2010/10/20 Javascript
解决js图片加载时出现404的问题
2020/11/30 Javascript
jQuery实现的分页功能示例
2017/01/22 Javascript
打造通用的匀速运动框架(实例讲解)
2017/10/17 Javascript
JavaScript实现三级级联特效
2017/11/05 Javascript
详解JS模块导入导出
2017/12/20 Javascript
JS实现不用中间变量temp 实现两个变量值得交换方法
2018/02/04 Javascript
安装vue-cli的简易过程
2018/05/22 Javascript
JS实现动态添加外部js、css到head标签的方法
2019/06/05 Javascript
vue自定义指令实现仅支持输入数字和浮点型的示例
2019/10/30 Javascript
利用Vue实现简易播放器的完整代码
2020/12/30 Vue.js
你应该知道的python列表去重方法
2017/01/17 Python
Django之无名分组和有名分组的实现
2019/04/16 Python
使用Python计算玩彩票赢钱概率
2019/06/26 Python
python接口调用已训练好的caffe模型测试分类方法
2019/08/26 Python
Python selenium的基本使用方法分析
2019/12/21 Python
Python的对象传递与Copy函数使用详解
2019/12/26 Python
tensorflow常用函数API介绍
2020/04/19 Python
CSS3径向渐变之大鱼吃小鱼之孤单的大鱼
2016/04/26 HTML / CSS
微信小程序之html5 canvas绘图并保存到系统相册
2019/06/20 HTML / CSS
美国正宗奢华复古手袋、珠宝及配饰网站:What Goes Around Comes Around
2018/07/21 全球购物
HOTEL INFO英国:搜索全球酒店
2019/08/08 全球购物
Java中compareTo和compare的区别
2016/04/12 面试题
网络安全方面的面试题
2016/01/07 面试题
个人简历的自荐信
2013/10/23 职场文书
体育馆的标语
2014/06/24 职场文书
工作时间擅自离岗检讨书
2014/10/24 职场文书
会议通知格式范文
2015/04/15 职场文书
如何使用Python提取Chrome浏览器保存的密码
2021/06/09 Python