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 if 想到的些问题
Mar 22 PHP
功能齐全的PHP发送邮件类代码附详细说明
Jul 10 PHP
Uchome1.2 1.5 代码学习 common.php
Apr 24 PHP
php文本转图片自动换行的方法
Mar 13 PHP
解析获取优酷视频真实下载地址的PHP源代码
Jun 26 PHP
PHP程序漏洞产生的原因分析与防范方法说明
Mar 06 PHP
PHP中unset,array_splice删除数组中元素的区别
Jul 28 PHP
学习php设计模式 php实现命令模式(command)
Dec 08 PHP
PHP 将dataurl转成图片image方法总结
Oct 14 PHP
ThinkPHP实现登录退出功能
Jun 29 PHP
TP5框架model常见操作示例小结【增删改查、聚合、时间戳、软删除等】
Apr 05 PHP
PHP 对象继承原理与简单用法示例
Apr 21 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
中国站长站 For Dede4.0 采集规则
2007/05/27 PHP
深入HTTP响应状态码速查表的详解
2013/06/07 PHP
PHP模拟http请求的方法详解
2016/11/09 PHP
phpfpm的作用和用法
2019/10/10 PHP
PHP ob缓存以及ob函数原理实例解析
2020/11/13 PHP
jQuery学习笔记(2)--用jquery实现各种模态提示框代码及项目构架
2013/04/08 Javascript
jQuery让控件左右移动的三种实现方法
2013/09/08 Javascript
JQuery中form验证出错信息的查看方法
2013/10/08 Javascript
javascript使用百度地图api和html5特性获取浏览器位置
2014/01/10 Javascript
jQuery中选择器小问题(新人难免遇到)
2014/03/31 Javascript
js使用cookie记录用户名的方法
2015/11/26 Javascript
jQuery可见性过滤选择器用法示例
2016/09/09 Javascript
JavaScript类的写法
2016/09/17 Javascript
Vue computed计算属性的使用方法
2017/07/14 Javascript
浅谈node中的exports与module.exports的关系
2017/08/01 Javascript
快速解决bootstrap下拉菜单无法隐藏的问题
2018/08/10 Javascript
JS执行控制之节流模式实例分析
2018/12/21 Javascript
一文了解vue-router之hash模式和history模式
2019/05/31 Javascript
原生JavaScript实现换肤
2021/02/19 Javascript
Python isinstance函数介绍
2015/04/14 Python
使用Python下的XSLT API进行web开发的简单教程
2015/04/15 Python
解析Python中的二进制位运算符
2015/05/13 Python
python+django加载静态网页模板解析
2017/12/12 Python
下载官网python并安装的步骤详解
2019/10/12 Python
Python字节单位转换实例
2019/12/05 Python
Flask中endpoint的理解(小结)
2019/12/11 Python
Pycharm 2020年最新激活码(亲测有效)
2020/09/18 Python
Python简单实现区域生长方式
2020/01/16 Python
Python TKinter如何自动关闭主窗口
2020/02/26 Python
PyTorch之nn.ReLU与F.ReLU的区别介绍
2020/06/27 Python
如何利用Python给自己的头像加一个小国旗(小月饼)
2020/10/02 Python
服务员岗位职责
2014/01/29 职场文书
社保委托书怎么写
2014/08/02 职场文书
营运督导岗位职责
2015/04/10 职场文书
2015年社区民政工作总结
2015/04/21 职场文书
2016年优秀教师先进事迹材料
2016/02/26 职场文书