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 相关文章推荐
多重?l件?合查?(一)
Oct 09 PHP
PHP 高手之路(三)
Oct 09 PHP
Php图像处理类代码分享
Jan 19 PHP
浅析php变量作用域的一些问题
Aug 08 PHP
php通过curl模拟登陆DZ论坛
May 11 PHP
symfony2.4的twig中date用法分析
Mar 18 PHP
Yii2中cookie用法示例分析
Jul 18 PHP
详解PHP中的序列化、反序列化操作
Mar 21 PHP
PHP用户注册邮件激活账户的实现代码
May 31 PHP
PHP实现生成数据字典功能示例
May 24 PHP
php5.6.x到php7.0.x特性小结
Aug 17 PHP
使用Entrust扩展包在laravel 中实现RBAC的功能
Mar 16 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 base64+gzinflate压缩编码和解码代码
2008/10/03 PHP
PHP数组操作汇总 php数组的使用技巧
2011/07/17 PHP
php将textarea数据提交到mysql出现很多空格的解决方法
2014/12/19 PHP
php使用post数组的键值创建同名变量并赋值的方法
2015/04/03 PHP
列举PHP的Yii 2框架的开发优势
2015/07/03 PHP
PHP性能分析工具xhprof的安装使用与注意事项
2017/12/19 PHP
浅谈thinkphp的nginx配置,以及重写隐藏index.php入口文件方法
2019/10/12 PHP
php使用redis的几种常见操作方式和用法示例
2020/02/20 PHP
33种Javascript 表格排序控件收集
2009/12/03 Javascript
url 特殊字符 传递参数解决方法
2010/01/01 Javascript
jQuery中jqGrid分页实现代码
2011/11/04 Javascript
基于jQuery的简单九宫格实现代码
2012/08/09 Javascript
javascript提取URL的搜索字符串中的参数(自定义函数实现)
2013/01/22 Javascript
Javascript实现简单二级下拉菜单实例
2014/06/15 Javascript
JavaScript实现基于Cookie的存储类实例
2015/04/10 Javascript
javascript仿百度输入框提示自动下拉补全
2016/01/07 Javascript
jquery心形点赞关注效果的简单实现
2016/11/14 Javascript
JS获得多个同name 的input输入框的值的实现方法
2017/01/09 Javascript
深入理解NodeJS 多进程和集群
2018/10/17 NodeJs
移动端自适应flexible.js的使用方法(不用三大框架,仅写一个单html页面使用)推荐
2019/04/02 Javascript
es6中class类静态方法,静态属性,实例属性,实例方法的理解与应用分析
2020/02/15 Javascript
js实现无限层级树形数据结构(创新算法)
2020/02/27 Javascript
Python科学计算环境推荐——Anaconda
2014/06/30 Python
python实现随机漫步算法
2018/08/27 Python
Python如何爬取微信公众号文章和评论(基于 Fiddler 抓包分析)
2019/06/28 Python
教你如何编写、保存与运行Python程序的方法
2019/07/12 Python
socket.io 和canvas 实现的共享画板功能
2019/05/22 HTML / CSS
理肤泉美国官网:La Roche-Posay
2018/01/17 全球购物
体育教育专业毕业生自荐信
2013/11/15 职场文书
人力资源经理的岗位职责范本
2014/02/28 职场文书
优秀少先队大队辅导员事迹材料
2014/05/04 职场文书
学校门卫岗位职责范本
2014/06/30 职场文书
2015年乡镇卫生院工作总结
2015/04/22 职场文书
应急管理工作总结2015
2015/05/04 职场文书
幼儿园小朋友毕业感言
2015/07/30 职场文书
20180830晚上第一届KSL半决赛 雨神vs解冻(二龙 三炮解说)
2022/04/01 星际争霸