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,js双版本
Sep 25 PHP
使用session判断用户登录用户权限(超简单)
Jun 08 PHP
php根据身份证号码计算年龄的实例代码
Jan 18 PHP
PHP URL参数获取方式的四种例子
Feb 28 PHP
php画图实例
Nov 05 PHP
PHP中使用循环实现的金字塔图形
Nov 08 PHP
php实现Mongodb自定义方式生成自增ID的方法
Mar 23 PHP
php查询whois信息的方法
Jun 08 PHP
无需数据库在线投票调查php代码
Jul 20 PHP
PHP编程实现计算抽奖概率算法完整实例
Aug 09 PHP
详解PHP如何更好的利用PHPstorm的自动提示
Aug 18 PHP
浅谈PHP中的Trait使用方法
Mar 22 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
Thinkphp模板标签if和eq的区别和比较实例分析
2015/07/01 PHP
PHP的Trait机制原理与用法分析
2019/10/18 PHP
TP5框架安全机制实例分析
2020/04/05 PHP
认识延迟时间为0的setTimeout
2008/05/16 Javascript
6个DIV 135或246间隔一秒轮番显示效果
2010/07/24 Javascript
jquery $.getJSON()跨域请求
2011/12/21 Javascript
javascript内存管理详细解析
2013/11/11 Javascript
jquery使用淘宝接口跨域查询手机号码归属地实例
2013/11/28 Javascript
通过pjax实现无刷新翻页(兼容新版jquery)
2014/01/31 Javascript
用JavaScript实现一个代码简洁、逻辑不复杂的多级树
2014/05/23 Javascript
jQuery ajax serialize() 方法使用示例
2014/11/02 Javascript
jQuery实现的简单折叠菜单(折叠面板)效果代码
2015/09/16 Javascript
jQuery获取attr()与prop()属性值的方法及区别介绍
2016/07/06 Javascript
javascript实现右下角广告框效果
2017/02/01 Javascript
vue2.0项目中使用Ueditor富文本编辑器示例代码
2017/08/14 Javascript
jQuery绑定事件方法及区别(bind,click,on,live,one)
2017/08/14 jQuery
JavaScript实现简单图片轮播效果
2017/08/21 Javascript
Vue服务器渲染Nuxt学习笔记
2018/01/31 Javascript
ES6 Object方法扩展的应用实例分析
2019/06/25 Javascript
iview form清除校验状态的实现
2019/09/19 Javascript
微信小程序仿抖音短视频切换效果的实例代码
2020/06/24 Javascript
Python实现的个人所得税计算器示例
2018/06/01 Python
浅谈python 中的 type(), dtype(), astype()的区别
2020/04/09 Python
Python matplotlib 绘制双Y轴曲线图的示例代码
2020/06/12 Python
德国低价购买灯具和家具网站:Style-home.de
2016/11/25 全球购物
在线购买廉价折扣书籍和小说:BookOutlet.com
2018/02/19 全球购物
Lungolivigno Fashion官网:高级时装在线购物
2020/10/17 全球购物
AOP的定义以及作用
2013/09/08 面试题
留学自荐信的技巧
2013/10/17 职场文书
实习评语
2013/12/16 职场文书
岗位职责风险防控
2014/02/18 职场文书
高中班级口号
2014/06/09 职场文书
幼儿园大班教师个人工作总结
2015/02/05 职场文书
2015初中政治教学工作总结
2015/07/21 职场文书
五一放假通知怎么写
2015/08/18 职场文书
剑指Offer之Java算法习题精讲二叉树专项训练
2022/03/21 Java/Android