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 相关文章推荐
echo(),print(),print_r()之间的区别?
Nov 19 PHP
PHP配置心得包含MYSQL5乱码解决
Nov 20 PHP
php使用正则过滤js脚本代码实例
May 10 PHP
php向js函数传参的几种方法
Aug 10 PHP
php实现的DateDiff和DateAdd时间函数代码分享
Aug 16 PHP
VPS中使用LNMP安装WordPress教程
Dec 28 PHP
php准确计算复活节日期的方法
Apr 18 PHP
php ajax实现文件上传进度条
Mar 29 PHP
PHP模板引擎Smarty内建函数详解
Apr 11 PHP
php7新特性的理解和比较总结
Apr 14 PHP
php中对象引用和复制实例分析
Aug 14 PHP
PHP dirname功能及原理实例解析
Oct 28 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
PHP4 与 MySQL 数据库操作函数详解
2006/12/06 PHP
PHP4和PHP5性能测试和对比 测试代码与环境
2007/08/17 PHP
让GoogleCode的SVN下的HTML文件在FireFox下正常显示.
2009/05/25 Javascript
javascript与CSS复习(三)
2010/06/29 Javascript
jquery 查找iframe父级页面元素的实现代码
2011/08/28 Javascript
node.js中的url.format方法使用说明
2014/12/10 Javascript
JS实现判断滚动条滚到页面底部并执行事件的方法
2014/12/18 Javascript
详解AngularJS中module模块的导入导出
2015/12/10 Javascript
nodejs的HTML分析利器node-jquery用法浅析
2016/11/08 NodeJs
vue+vux实现移动端文件上传样式
2017/07/28 Javascript
本地存储localStorage用法详解
2017/07/31 Javascript
bootstrap Table服务端处理分页(后台是.net)
2017/10/19 Javascript
用ES6的class模仿Vue写一个双向绑定的示例代码
2018/04/20 Javascript
微信小程序模拟cookie的实现
2018/06/20 Javascript
浅谈express.js框架中间件(middleware)
2019/04/07 Javascript
详解Vue、element-ui、axios实现省市区三级联动
2019/05/07 Javascript
Centos7 安装Node.js10以上版本的方法步骤
2019/10/15 Javascript
Python中模块string.py详解
2017/03/12 Python
python获取指定字符串中重复模式最高的字符串方法
2018/06/29 Python
对python xlrd读取datetime类型数据的方法详解
2018/12/26 Python
python对文件的操作方法汇总
2020/02/28 Python
python 制作网站小说下载器
2021/02/20 Python
HTML5中input[type='date']自定义样式与日历校验功能的实现代码
2017/07/11 HTML / CSS
名人演讲稿范文
2013/12/28 职场文书
现场施工员岗位职责
2014/03/10 职场文书
《三顾茅庐》教学反思
2014/04/10 职场文书
个人安全承诺书
2014/05/22 职场文书
会计专业毕业生自荐书
2014/06/25 职场文书
环保志愿者活动总结
2014/06/27 职场文书
大学竞选班干部演讲稿
2014/08/21 职场文书
初中教师个人总结
2015/02/10 职场文书
在职人员跳槽求职信
2015/03/20 职场文书
爱心捐款活动总结
2015/05/09 职场文书
Python OpenGL基本配置方式
2022/05/20 Python
Nginx报错104:Connection reset by peer问题的解决及分析
2022/07/23 Servers