php使用gearman进行任务分发操作实例详解


Posted in PHP onFebruary 26, 2020

本文实例讲述了php使用gearman进行任务分发操作。分享给大家供大家参考,具体如下:

一、安装gearman

下载gearman源码包

https://launchpad.net/gearmand/+download

如: gearmand-1.1.12.tar.gz

下载php的gearman扩展包

http://pecl.php.net/package/gearman

如: gearman-1.1.2.tgz

安装gearman

> yum install boost-devel gperf libevent-devel libuuid-devel
> tar xf gearmand-1.1.12.tar.gz
> cd gearmand-1.1.12
> ./configure
> make && make install

安装gearman的php扩展(建议php版本不要过高,因为php7的gearman扩展目前还没有出来)

> yum install autoconf
> tar xf gearman-1.1.2.tgz
> cd gearman-1.1.2
> /data/php56/bin/phpize
> ./configure --with-php-config=/data/php56/bin/php-config
> make && make install

修改php.ini

> vi /data/php56/lib/php.ini

添加如下两项

extension_dir=/data/php56/lib/php/extensions/no-debug-zts-20131226/
extension=gearman.so

查看扩展

> /data/php56/bin/php -m

二、简单的使用gearman

gearman中请求的处理过程一般涉及三种角色:client->job->worker
其中client是请求的发起者
job是请求的调度者,用于把客户的请求分发到不同的worker上进行工作
worker是请求的处理者

比如这里我们要处理client向job发送一个请求,来计算两个数之和,job负责调度worker来具体实现计算两数之和。

首先我们编写client.php

<?php
//创建一个客户端
$client = new GearmanClient();
//添加一个job服务
$client->addServer('127.0.0.1', 4730);
//doNormal是同步的,等待worker处理完成返回结果
//建议不要使用do()了
$ret = $client->doNormal('sum', serialize(array(10, 10)));

if($ret) {
  echo '计算结果:', $ret, "\n";
}

再编写worker.php

<?php
//创建一个worker
$worker = new GearmanWorker();
//添加一个job服务
$worker->addServer('127.0.0.1', 4730);
//注册一个回调函数,用于业务处理
$worker->addFunction('sum', function($job) {
  //workload()获取客户端发送来的序列化数据
  $data = unserialize($job->workload());

  return $data[0] + $data[1];
});

//死循环
while(true) {
  //等待job提交的任务
  $ret = $worker->work();
  if ($worker->returnCode() != GEARMAN_SUCCESS) {
    break;
  }
}

我们先启动gearmand服务

> mkdir -p /usr/local/var/log
> gearmand -d

运行worker文件

> /data/php56/bin/php /data/worker.php

再运行client文件

> /data/php56/bin/php /data/client.php

结果如下:

php使用gearman进行任务分发操作实例详解

三、gearman异步的处理任务

这里我们client向job发送一个发送邮件的请求,不等待请求完成,继续向下执行。

client.php代码如下:

<?php
//创建一个客户端
$client = new GearmanClient();
//添加一个job服务
$client->addServer('127.0.0.1', 4730);
//doBackground异步,返回提交任务的句柄
$ret = $client->doBackground('sendEmail', json_encode(array(
  'email' => 'test@qq.com',
  'title' => '测试异步',
  'body' => '异步执行好牛B的样子',
)));

//继续执行下面的代码
echo "我的内心毫无波动,甚至还想笑\n";

do {
  sleep(1);

  //获取任务句柄的状态
  //jobStatus返回的是一个数组
  //第一个,表示工作是否已经知道
  //第二个,工作是否在运行
  //第三和第四,分别对应完成百分比的分子与分母
  $status = $client->jobStatus($ret);
  
  echo "完成情况:{$status[2]}/{$status[3]}\n";

  if(!$status[1]) {
    break;
  }
} while(true);

worker.php代码如下:

<?php
//创建一个worker
$worker = new GearmanWorker();
//添加一个job服务
$worker->addServer('127.0.0.1', 4730);
//注册一个回调函数,用于业务处理
$worker->addFunction('sendEmail', function($job) {
  //workload()获取客户端发送来的序列化数据
  $data = json_decode($job->workload(), true);
  //模拟发送邮件所用时间
  sleep(6);
  echo "发送{$data['email']}邮件成功\n";
});

//死循环
//等待job提交的任务
while($worker->work());

结果如下:

php使用gearman进行任务分发操作实例详解

四、gearman并行的执行多个任务

我们如何并行的计算两个数的累加和? 通过addTask添加多个任务到队列,然后进行并行计算。

client.php代码如下:

<?php
//创建一个客户端
$client = new GearmanClient();
//添加一个job服务
$client->addServer('127.0.0.1', 4730);
//设置任务完成时的回调函数
$client->setCompleteCallback(function($task) {
  //获取由worker返回的数据
  echo $task->data(), "\n";
});

//计算1到500的累加和
//添加五个任务到队列
$client->addTask('sum', json_encode(array(1, 100)));
$client->addTask('sum', json_encode(array(100, 200)));
$client->addTask('sum', json_encode(array(200, 300)));
$client->addTask('sum', json_encode(array(300, 400)));
$client->addTask('sum', json_encode(array(400, 500)));

//运行队列中的任务,do系列不需要runTask()
$client->runTasks();

worker.php代码如下:

<?php
//创建一个worker
$worker = new GearmanWorker();
//添加一个job服务
$worker->addServer('127.0.0.1', 4730);
//注册一个回调函数,用于业务处理
$worker->addFunction('sum', function($job) {
  //workload()获取客户端发送来的序列化数据
  $data = json_decode($job->workload(), true);
  sleep(1);
  $sum = 0;
  for($ix = $data[0]; $ix < $data[1]; ++$ix) {
    $sum += $ix;
  }
  return $sum;
});

//死循环
//等待job提交的任务
while($worker->work());

我们开启5个worker工作进程,当运行客户端请求时,5个计算任务几乎是同时返回结果。

结果如下:

php使用gearman进行任务分发操作实例详解

php使用gearman进行任务分发操作实例详解

希望本文所述对大家PHP程序设计有所帮助。

PHP 相关文章推荐
PHP+AJAX实现无刷新注册(带用户名实时检测)
Jan 02 PHP
自己前几天写的无限分类类
Feb 14 PHP
php中的实现trim函数代码
Mar 19 PHP
谈PHP生成静态页面分析 模板+缓存+写文件
Aug 17 PHP
PHP 程序员应该使用的10个组件
Oct 31 PHP
完美解决令人抓狂的zend studio 7代码提示(content Assist)速度慢的问题
Jun 20 PHP
利用yahoo汇率接口实现实时汇率转换示例 汇率转换器
Jan 14 PHP
CodeIgniter常用知识点小结
May 26 PHP
PHP静态成员变量和非静态成员变量详解
Feb 14 PHP
php简单构造json多维数组的方法示例
Jun 08 PHP
PHP实现的CURL非阻塞调用类
Jul 26 PHP
PHP设计模式之装饰器(装饰者)模式(Decorator)入门与应用详解
Dec 13 PHP
php实现根据身份证获取精准年龄
Feb 26 #PHP
ThinkPHP5与单元测试PHPUnit使用详解
Feb 23 #PHP
PHP实现创建一个RPC服务操作示例
Feb 23 #PHP
php 使用ActiveMQ发送消息,与处理消息操作示例
Feb 23 #PHP
php实现通过stomp协议连接ActiveMQ操作示例
Feb 23 #PHP
php ActiveMQ的安装与使用方法图文教程
Feb 23 #PHP
php 多进程编程父进程的阻塞与非阻塞实例分析
Feb 22 #PHP
You might like
十天学会php之第九天
2006/10/09 PHP
PHP中PDO的错误处理
2011/09/04 PHP
PHP中使用smarty生成静态文件的例子
2014/04/24 PHP
php获取文件类型和文件信息的方法
2015/07/10 PHP
PHP操作redis实现的分页列表,新增,删除功能封装类与用法示例
2018/08/04 PHP
php使用gearman进行任务分发操作实例详解
2020/02/26 PHP
Laravel框架数据库迁移操作实例详解
2020/04/06 PHP
PhpSpreadsheet设置单元格常用操作汇总
2020/11/13 PHP
求得div 下 img的src地址的js代码
2007/02/28 Javascript
javascript 面向对象全新理练之数据的封装
2009/12/03 Javascript
页面定时刷新(1秒刷新一次)
2013/11/22 Javascript
将list转换为json失败的原因
2013/12/17 Javascript
pace.js页面加载进度条插件
2015/09/29 Javascript
webpack打包js文件及部署的实现方法
2017/12/18 Javascript
JS实现十字坐标跟随鼠标效果
2017/12/25 Javascript
解决Angular.js中使用Swiper插件不能滑动的问题
2018/02/26 Javascript
微信小程序实现留言板功能
2018/11/02 Javascript
bootstrap table实现iview固定列的效果实例代码详解
2019/09/30 Javascript
vue实现员工信息录入功能
2020/06/11 Javascript
VUE前端从后台请求过来的数据进行转换数据结构操作
2020/11/11 Javascript
JS中多层次排序算法的实现代码
2021/01/06 Javascript
[04:21]狐狸妈带你到现场 DOTA2 TI中国区预选赛线下赛路线指引
2014/05/22 DOTA
[01:52]DOTA2完美大师赛Vega战队趣味视频——kpii老师小课堂
2017/11/25 DOTA
numpy 进行数组拼接,分别在行和列上合并的实例
2018/05/08 Python
python操作mysql代码总结
2018/06/01 Python
Pycharm无法使用已经安装Selenium的解决方法
2018/10/13 Python
pyenv与virtualenv安装实现python多版本多项目管理
2019/08/17 Python
python实现串口通信的示例代码
2020/02/10 Python
Django DRF认证组件流程实现原理详解
2020/08/17 Python
解决python的空格和tab混淆而报错的问题
2021/02/26 Python
澳大利亚最大的百货公司:Myer
2018/12/21 全球购物
个人简历中的自我评价范例
2013/10/29 职场文书
电子商务专业个人的自我评价
2013/11/19 职场文书
优秀英语专业毕业生求职信
2013/11/23 职场文书
2015年药店工作总结
2015/04/20 职场文书
一些让Python代码简洁的实用技巧总结
2021/08/23 Python