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 相关文章推荐
一个简易需要注册的留言版程序
Oct 09 PHP
经典的PHPer为什么被认为是草根?
Apr 02 PHP
关于PHP中Object对象的笔记分享
Jun 28 PHP
彻底删除thinkphp3.1案例blog标签的方法
Dec 05 PHP
ThinkPHP中order()使用方法详解
Apr 19 PHP
支付宝支付开发――当面付条码支付和扫码支付实例
Nov 04 PHP
PHP对象、模式与实践之高级特性分析
Dec 08 PHP
php PDO实现的事务回滚示例
Mar 23 PHP
PHP依赖注入(DI)和控制反转(IoC)详解
Jun 12 PHP
PHP设计模式之原型模式定义与用法详解
Apr 03 PHP
关于Curl在Swoole协程中的解决方案详析
Sep 12 PHP
php中关于换行的实例写法
Sep 26 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
超神学院:鹤熙已踏入神圣领域,实力不比凯莎弱
2020/03/02 国漫
JAVA/JSP学习系列之二
2006/10/09 PHP
PHP查询快递信息的方法
2015/03/07 PHP
php微信公众号开发(4)php实现自定义关键字回复
2016/12/15 PHP
thinkphp5框架扩展redis类方法示例
2019/05/06 PHP
window.location不跳转的问题解决方法
2014/04/17 Javascript
JavaScript window.location对象
2014/11/14 Javascript
浅析jQuery中使用$所引发的问题
2016/05/29 Javascript
jQuery增加和删除表格项目及实现表格项目排序的方法
2016/05/30 Javascript
文件上传,iframe跨域数据提交的实现
2016/11/18 Javascript
javascript学习之json入门
2016/12/22 Javascript
微信小程序 定位到当前城市实现实例代码
2017/02/23 Javascript
Vuex模块化实现待办事项的状态管理
2017/03/15 Javascript
解析NodeJS异步I/O的实现
2017/04/13 NodeJs
Angular4集成ng2-file-upload的上传组件
2018/03/14 Javascript
vue如何判断dom的class
2018/04/26 Javascript
Vue项目webpack打包部署到Tomcat刷新报404错误问题的解决方案
2018/05/15 Javascript
JavaScript实现与使用发布/订阅模式详解
2019/01/19 Javascript
vue 项目 iOS WKWebView 加载
2019/04/17 Javascript
详解ES6 Promise的生命周期和创建
2019/08/18 Javascript
python中Genarator函数用法分析
2015/04/08 Python
python利用微信公众号实现报警功能
2018/06/10 Python
详解PyCharm+QTDesigner+PyUIC使用教程
2019/06/13 Python
python给指定csv表格中的联系人群发邮件(带附件的邮件)
2019/12/31 Python
Python叠加矩形框图层2种方法及效果
2020/06/18 Python
使用HTML5在网页中嵌入音频和视频播放的基本方法
2016/02/22 HTML / CSS
美国派对用品及装饰品网上商店:Shindigz
2016/07/30 全球购物
几个Shell Script面试题
2014/04/18 面试题
两道JAVA笔试题
2016/09/14 面试题
入党自我鉴定范文
2013/10/04 职场文书
2014年领班工作总结
2014/11/25 职场文书
学生保证书格式
2015/02/27 职场文书
关爱留守儿童主题班会
2015/08/13 职场文书
Mysql 性能监控及调优
2021/04/06 MySQL
python基于opencv批量生成验证码的示例
2021/04/28 Python
用JS实现飞机大战小游戏
2021/06/09 Javascript