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版(1)
Oct 09 PHP
C# Assembly类访问程序集信息
Jun 13 PHP
PHP 最大运行时间 max_execution_time修改方法
Mar 08 PHP
模板引擎正则表达式调试小技巧
Jul 20 PHP
php后退一页表单内容保存实现方法
Jun 17 PHP
php实现监听事件
Nov 06 PHP
php命名空间学习详解
Feb 27 PHP
如何使用PHP Embed SAPI实现Opcodes查看器
Nov 10 PHP
PHP浮点比较大小的方法
Feb 14 PHP
Symfony核心类概述
Mar 17 PHP
PHP实现批量检测网站是否能够正常打开的方法
Aug 23 PHP
PHP实现上传多文件示例代码
Feb 20 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 生成WML页面方法详解
2009/08/09 PHP
PHP+Mysql树型结构(无限分类)数据库设计的2种方式实例
2014/07/15 PHP
标准PHP的AES加密算法类
2015/03/12 PHP
php is_executable判断给定文件名是否可执行实例
2016/09/26 PHP
javascript 当前日期转化为中文的实现代码
2010/05/13 Javascript
jQuery EasyUI API 中文文档 - Dialog对话框
2011/11/15 Javascript
指定区域的图片自动按比例缩小的js代码(防止页面被图片撑破)
2014/02/21 Javascript
jquery 构造函数在表单提交过程中修改数据
2015/05/25 Javascript
详解JavaScript操作HTML DOM的基本方式
2015/10/21 Javascript
js实现瀑布流效果(自动生成新的内容)
2017/03/16 Javascript
详解Angular.js数据绑定时自动转义html标签及内容
2017/03/30 Javascript
JavaScript之事件委托实例(附原生js和jQuery代码)
2017/07/22 jQuery
Vue不能观察到数组length的变化
2018/06/08 Javascript
vue v-model动态生成详解
2018/06/30 Javascript
node运行js获得输出的三种方式示例详解
2020/07/02 Javascript
[03:24]CDEC.Y赛前采访 努力备战2016国际邀请赛中国区预选赛
2016/06/25 DOTA
python中使用百度音乐搜索的api下载指定歌曲的lrc歌词
2014/07/18 Python
解析Python中的异常处理
2015/04/28 Python
在Python的Django框架中使用通用视图的方法
2015/07/21 Python
老生常谈Python之装饰器、迭代器和生成器
2017/07/26 Python
python与caffe改变通道顺序的方法
2018/08/04 Python
Python编程中类与类的关系详解
2019/08/08 Python
PyTorch中Tensor的拼接与拆分的实现
2019/08/18 Python
详解django中Template语言
2020/02/22 Python
520使用Python实现“我爱你”表白
2020/05/20 Python
Python openpyxl模块实现excel读写操作
2020/06/30 Python
Python列表嵌套常见坑点及解决方案
2020/09/30 Python
HTML5 表单验证失败的提示语问题
2017/07/13 HTML / CSS
欧洲第一中国智能手机和平板电脑网上商店:CECT-SHOP
2018/01/08 全球购物
Glamest意大利:女性在线奢侈品零售店
2019/04/28 全球购物
DOM和JQuery对象有什么区别
2016/11/11 面试题
高分子材料个人求职信范文
2013/09/25 职场文书
打架检讨书500字
2014/01/29 职场文书
销售内勤岗位职责
2015/02/10 职场文书
党性教育心得体会(共6篇)
2016/01/21 职场文书
导游词之河北野三坡
2019/12/11 职场文书