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获取表单textarea数据中的换行问题
Sep 10 PHP
利用PHP实现智能文件类型检测的实现代码
Aug 02 PHP
微信营销平台系统?刮刮乐的开发
Jun 10 PHP
php实现读取和写入tab分割的文件
Jun 01 PHP
Codeigniter控制器controller继承问题实例分析
Jan 19 PHP
Thinkphp单字母函数使用指南
May 08 PHP
PHP在linux上执行外部命令的方法
Feb 06 PHP
PHP实现对数组分页处理实例详解
Feb 07 PHP
PHP使用SWOOLE扩展实现定时同步 MySQL 数据
Apr 09 PHP
PHP实现简单登录界面
Oct 23 PHP
laravel框架语言包拓展实现方法分析
Nov 22 PHP
Centos7安装swoole扩展操作示例
Mar 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
PHP获取文件行数的方法
2015/06/10 PHP
在Linux系统下一键重新安装WordPress的脚本示例
2015/06/30 PHP
PHP并发查询MySQL的实例代码
2017/08/09 PHP
MacOS下PHP7.1升级到PHP7.4.15的方法
2021/02/22 PHP
Maps Javascript
2007/01/22 Javascript
js 父窗口控制子窗口的行为-打开,关闭,重定位,回复
2010/04/20 Javascript
基于Jquery的仿照flash放大图片效果代码
2011/03/16 Javascript
Javascript基础知识(二)事件
2014/09/29 Javascript
常用的JS验证和函数汇总
2014/12/23 Javascript
vue.js 表格分页ajax 异步加载数据
2016/10/18 Javascript
Angular工具方法学习
2016/12/26 Javascript
discuz表情的JS提取方法分析
2017/03/22 Javascript
Vue2.0基于vue-cli+webpack Vuex的用法(实例讲解)
2017/09/15 Javascript
JS操作json对象key、value的常用方法分析
2019/10/29 Javascript
9种python web 程序的部署方式小结
2014/06/30 Python
python绘图方法实例入门
2015/05/19 Python
Python制作简易注册登录系统
2016/12/15 Python
通过python将大量文件按修改时间分类的方法
2018/10/17 Python
在python中利用KNN实现对iris进行分类的方法
2018/12/11 Python
浅谈Python反射 &amp; 单例模式
2019/03/21 Python
python对象转字典的两种实现方式示例
2019/11/07 Python
python字符串的拼接方法总结
2019/11/18 Python
Tensorflow训练MNIST手写数字识别模型
2020/02/13 Python
借助HTML5 Canvas API制作一个简单的猜字游戏
2016/03/25 HTML / CSS
加拿大消费电子和手机购物网站:The Source
2017/01/28 全球购物
Lou & Grey美国官网:主打舒适性面料服饰
2017/12/21 全球购物
美国在线纱线商店:Darn Good Yarn
2019/03/20 全球购物
高二历史教学反思
2014/01/25 职场文书
团日活动总结书格式
2014/05/08 职场文书
我的中国梦演讲稿400字
2014/08/19 职场文书
2014年社区妇联工作总结
2014/12/02 职场文书
客户经理岗位职责大全
2015/04/09 职场文书
2016年离婚协议书范文
2016/03/18 职场文书
Python合并pdf文件的工具
2021/07/01 Python
CSS3实现360度循环旋转功能
2022/02/12 HTML / CSS
Python测试框架pytest高阶用法全面详解
2022/06/01 Python