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文件向另一个地址post数据,不用表单和隐藏的变量的
Mar 06 PHP
用php+javascript实现二级级联菜单的制作
May 06 PHP
让Json更懂中文(JSON_UNESCAPED_UNICODE)
Oct 27 PHP
关于PHP模板Smarty的初级使用方法以及心得分享
Jun 21 PHP
CI(CodeIgniter)框架中的增删改查操作
Jun 10 PHP
thinkphp四种url访问方式详解
Nov 28 PHP
PHP实现根据时间戳获取周几的方法
Feb 26 PHP
PHP会员找回密码功能的简单实现
Sep 05 PHP
php入门教程之Zend Studio设置与开发实例
Sep 09 PHP
thinkPHP内置字符串截取函数用法详解
Nov 15 PHP
浅谈PHP的反射机制
Dec 15 PHP
YII2自动登录Cookie总是失效的解决方法
Jun 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数学运算
2011/12/30 PHP
探讨php define()函数及defined()函数使用详解
2013/06/09 PHP
PHP简单实现DES加密解密的方法
2016/07/12 PHP
py文件转exe时包含paramiko模块出错解决方法
2016/08/12 PHP
jquery trim() 功能源代码
2011/02/14 Javascript
Javascript学习笔记-详解in运算符
2011/09/13 Javascript
jcrop基本参数一览
2013/07/16 Javascript
jQuery怎么解析Json字符串(Json格式/Json对象)
2013/08/09 Javascript
jQuery scrollFix滚动定位插件
2015/04/01 Javascript
Javascript点击按钮随机改变数字与其颜色
2016/09/01 Javascript
AngularJS 所有版本下载地址
2016/09/14 Javascript
BootStrap与Select2使用小结
2017/02/17 Javascript
canvas雪花效果核心代码分享
2017/02/19 Javascript
用Axios Element实现全局的请求loading的方法
2018/03/15 Javascript
JavaScript显式数据类型转换详解
2019/03/18 Javascript
vue+elementUI实现表单和图片上传及验证功能示例
2019/05/14 Javascript
vue实现简单计算商品价格
2020/09/14 Javascript
python脚本实现xls(xlsx)转成csv
2016/04/10 Python
Django框架实现的普通登录案例【使用POST方法】
2019/05/15 Python
Python实现将蓝底照片转化为白底照片功能完整实例
2019/12/13 Python
Python实现遗传算法(二进制编码)求函数最优值方式
2020/02/11 Python
Pycharm+Python工程,引用子模块的实现
2020/03/09 Python
python支持多继承吗
2020/06/19 Python
浅析Python 条件控制语句
2020/07/15 Python
利用CSS3实现文字折纸效果实例代码
2018/07/10 HTML / CSS
使用css如何制作时间ICON方法实践
2012/11/12 HTML / CSS
全球速卖通俄罗斯站:AliExpress俄罗斯
2019/06/17 全球购物
西班牙在线光学:Visual-Click
2020/06/22 全球购物
领先的荷兰线上超市:荷兰之家Holland at Home(支持中文)
2021/01/21 全球购物
和谐家庭演讲稿
2014/05/24 职场文书
幼儿园中秋节活动总结
2015/03/23 职场文书
大学生村官工作总结2015
2015/04/09 职场文书
停课通知书
2015/04/24 职场文书
丧事酒宴答谢词
2015/09/30 职场文书
教师个人工作总结范文2015
2015/10/14 职场文书
企业团队精神心得体会
2016/01/19 职场文书