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 相关文章推荐
类的另类用法--数据的封装
Oct 09 PHP
php 如何获取数组第一个值
Aug 06 PHP
php解决抢购秒杀抽奖等大流量并发入库导致的库存负数的问题
Jun 19 PHP
Linux下安装PHP MSSQL扩展教程
Oct 24 PHP
Linux操作系统安装LAMP环境
Jun 26 PHP
PHP测试成功的邮件发送案例
Oct 26 PHP
Zend Framework教程之Application和Bootstrap用法详解
Mar 10 PHP
PHP 无限级分类
May 04 PHP
php使用PDO从数据库表中读取数据的实现方法(必看)
Jun 02 PHP
thinkPHP5框架分页样式类完整示例
Sep 01 PHP
Laravel timestamps 设置为unix时间戳的方法
Oct 11 PHP
Yii使用DbTarget实现日志功能的示例代码
Jul 21 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
PHP5函数小全(分享)
2013/06/06 PHP
ThinkPHP实现支付宝接口功能实例
2014/12/02 PHP
php利用scws实现mysql全文搜索功能的方法
2014/12/25 PHP
PHP实现微信小程序人脸识别刷脸登录功能
2018/05/24 PHP
jQuery EasyUI API 中文文档 - ProgressBar 进度条
2011/09/29 Javascript
js中对象的声明方式以及数组的一些用法示例
2013/12/11 Javascript
javascript解析json数据的3种方式
2014/05/08 Javascript
再谈Jquery Ajax方法传递到action(补充)
2014/05/12 Javascript
javascript实现 百度翻译 可折叠的分享按钮列表
2015/03/12 Javascript
jquery图片倾斜层叠切换特效代码分享
2015/08/27 Javascript
微信小程序 教程之列表渲染
2016/10/18 Javascript
JavaScript登录验证码的实现
2016/10/27 Javascript
js实现tab选项卡切换功能
2017/01/13 Javascript
javascript实现动态显示颜色块的报表效果
2017/04/10 Javascript
vue事件修饰符和按键修饰符用法总结
2017/07/25 Javascript
微信小程序 页面滑动事件的实例详解
2017/10/12 Javascript
浅谈vuepress 踩坑记
2018/04/18 Javascript
区别JavaScript函数声明与变量声明
2018/09/12 Javascript
详解React服务端渲染从入门到精通
2019/03/28 Javascript
vue-cli3 项目优化之通过 node 自动生成组件模板 generate View、Component
2019/04/30 Javascript
layui文件上传控件带更改后数据传值的方法
2019/09/23 Javascript
NodeJS http模块用法示例【创建web服务器/客户端】
2019/11/05 NodeJs
利用JavaScript为句子加标题的3种方法示例
2021/01/05 Javascript
[01:04]不如跳舞!DOTA2新英雄玛尔斯的欢乐日常
2019/03/11 DOTA
python分析网页上所有超链接的方法
2015/05/08 Python
Python并发编程协程(Coroutine)之Gevent详解
2017/12/27 Python
python实现音乐下载的统计
2018/06/20 Python
python实现自动获取IP并发送到邮箱
2018/12/26 Python
关于python中密码加盐的学习体会小结
2019/07/15 Python
Python实现性能自动化测试竟然如此简单
2019/07/30 Python
浅谈python中频繁的print到底能浪费多长时间
2020/02/21 Python
P D PAOLA法国官网:西班牙著名的珠宝首饰品牌
2020/02/15 全球购物
公司委托书格式范文
2014/04/04 职场文书
保险专业求职信
2014/07/07 职场文书
新党章的学习心得体会
2014/11/07 职场文书
大学生自荐信范文
2015/03/05 职场文书