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作为Shell脚本语言使用
Oct 09 PHP
缓存技术详谈―php
Dec 14 PHP
PHP中通过语义URL防止网站被攻击的方法分享
Sep 08 PHP
PHP fgetcsv 定义和用法(附windows与linux下兼容问题)
May 29 PHP
获取php页面执行时间,数据库读写次数,函数调用次数等(THINKphp)
Jun 03 PHP
PHP strstr 函数判断字符串是否否存在的实例代码
Sep 28 PHP
php强制文件下载而非在浏览器打开的自定义函数分享
May 08 PHP
ci检测是ajax还是页面post提交数据的方法
Nov 10 PHP
PHP实现简单汉字验证码
Jul 28 PHP
PHP实现的CURL非阻塞调用类
Jul 26 PHP
PHP调用QQ互联接口实现QQ登录网站功能示例
Oct 24 PHP
浅谈PHP中的那些魔术常量
Dec 02 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的sprintf函数的用法 控制浮点数格式
2014/02/14 PHP
PHP中的随机性 你觉得自己幸运吗?
2016/01/22 PHP
用Laravel Sms实现laravel短信验证码的发送的实现
2018/11/29 PHP
Yii2框架自定义类统一处理url操作示例
2019/05/25 PHP
PHP使用ActiveMQ实现消息队列的方法详解
2019/05/31 PHP
javascript form 验证函数 弹出对话框形式
2009/06/23 Javascript
js隐藏与显示回到顶部按钮及window.onscroll事件应用
2013/01/25 Javascript
jquery实现的可隐藏重现的靠边悬浮层实例代码
2013/05/27 Javascript
鼠标经过显示二级菜单js特效
2013/08/13 Javascript
javascript自定义startWith()和endWith()的两种方法
2013/11/11 Javascript
jQuery select表单提交省市区城市三级联动核心代码
2014/06/09 Javascript
关闭页面时window.location事件未执行的原因分析及解决方案
2014/09/01 Javascript
用javascript实现自动输出网页文本
2015/07/30 Javascript
简单实现异步编程promise模式
2015/07/31 Javascript
jQuery+JSON实现AJAX二级联动实例分析
2015/12/18 Javascript
Javascript OOP之面向对象
2016/07/31 Javascript
KVM虚拟化技术之使用Qemu-kvm创建和管理虚拟机的方法
2016/10/05 Javascript
基于EasyUI的基础之上实现树形功能菜单
2017/06/28 Javascript
微信小程序 sha1 实现密码加密实例详解
2017/07/06 Javascript
JavaScript基础教程之如何实现一个简单的promise
2018/09/11 Javascript
JS 数组和对象的深拷贝操作示例
2020/06/06 Javascript
微信小程序淘宝首页双排图片布局排版代码(推荐)
2020/10/29 Javascript
python实现爬山算法的思路详解
2019/04/09 Python
python脚本当作Linux中的服务启动实现方法
2019/06/28 Python
pytorch查看通道数 维数 尺寸大小方式
2020/05/26 Python
8款使用 CSS3 实现超炫的 Loading(加载)的动画效果
2015/03/17 HTML / CSS
HTML5在微信内置浏览器下右上角菜单的调整字体导致页面显示错乱的问题
2021/01/19 HTML / CSS
Merchant 1948澳大利亚:新西兰领先的鞋类和靴子供应商
2018/03/24 全球购物
香港彩色隐形眼镜在线商店:Stunninglens(全球免费送货)
2019/05/10 全球购物
汽车检测与维修应届毕业生求职信
2013/10/19 职场文书
服务之星事迹材料
2014/05/03 职场文书
信息与工商管理职业规划范文:为梦想而搏击
2014/09/11 职场文书
2014年国庆节广播稿
2014/09/19 职场文书
《揠苗助长》教学反思
2016/02/20 职场文书
如何计划开一家便利店?
2019/07/31 职场文书
CentOS7和8下安装Maven3.8.4
2022/04/07 Servers