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 相关文章推荐
ajax+php打造进度条 readyState各状态
Mar 20 PHP
用PHP的超级变量$_POST获取HTML表单(HTML Form) 数据
May 07 PHP
PHP取整数函数常用的四种方法小结
Jul 05 PHP
php使用strtotime和date函数判断日期是否有效代码分享
Dec 25 PHP
PHP实现的MongoDB数据库操作类分享
May 12 PHP
PHP中应该避免使用同名变量(拆分临时变量)
Apr 03 PHP
CI框架简单邮件发送类实例
May 18 PHP
Laravel如何使用数据库事务及捕获事务失败后的异常详解
Oct 23 PHP
PHP类的自动加载机制实现方法分析
Jan 10 PHP
php利用array_search与array_column实现二维数组查找
Jul 08 PHP
Laravel框架Auth用户认证操作实例分析
Sep 29 PHP
Laravel基础_关于view共享数据的示例讲解
Oct 14 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中截取字符串支持utf-8
2007/01/18 PHP
Yii操作数据库的3种方法
2014/03/11 PHP
PHP 验证登陆类分享
2015/03/13 PHP
在Win2003(64位)中配置IIS6+PHP5.2.17+MySQL5.5的运行环境
2016/04/04 PHP
PHP链表操作简单示例
2016/10/15 PHP
PHP实现的XXTEA加密解密算法示例
2018/08/28 PHP
JavaScript call apply使用 JavaScript对象的方法绑定到DOM事件后this指向问题
2011/09/28 Javascript
Jquery显示和隐藏元素或设为只读(含Ligerui的控件禁用,实例说明介绍)
2013/07/09 Javascript
纯js代码实现未知宽高的元素在指定元素中垂直水平居中显示
2015/09/12 Javascript
javascript简单判断输入内容是否合法的方法
2016/05/11 Javascript
JS实现页面打印(整体、局部)
2017/08/18 Javascript
js实现登录注册框手机号和验证码校验(前端部分)
2017/09/28 Javascript
vue-cli 首屏加载优化问题
2018/11/06 Javascript
layui实现左侧菜单点击右侧内容区显示
2019/07/26 Javascript
layui下拉列表select实现可输入查找的方法
2019/09/28 Javascript
vue router 传参获取不到的解决方式
2019/11/13 Javascript
JS使用setInterval计时器实现挑战10秒
2020/11/08 Javascript
web.py在模板中输出美元符号的方法
2014/08/26 Python
python抓取网页中图片并保存到本地
2015/12/01 Python
Python中index()和seek()的用法(详解)
2017/04/27 Python
Python编程实现双击更新所有已安装python模块的方法
2017/06/05 Python
教你用Python创建微信聊天机器人
2020/03/31 Python
Tensorflow 查看变量的值方法
2018/06/14 Python
使用python脚本实现查询火车票工具
2018/07/19 Python
Python Pandas批量读取csv文件到dataframe的方法
2018/10/08 Python
你不知道的葡萄干处理法、橙蜜处理法、二氧化碳酵母法
2021/03/17 冲泡冲煮
浅析移动设备HTML5页面布局
2015/12/01 HTML / CSS
详解HTML5中表单验证的8种方法介绍
2016/12/19 HTML / CSS
照片礼物和装饰:MyPhoto
2019/11/02 全球购物
大学生职业生涯规划书模版
2013/12/30 职场文书
2014年清明节寄语
2014/04/03 职场文书
新年寄语大全
2014/04/12 职场文书
学校四风对照检查材料
2014/08/28 职场文书
2019经典广告词集锦!
2019/07/02 职场文书
Pytorch GPU内存占用很高,但是利用率很低如何解决
2021/06/01 Python
MySQL 服务和数据库管理
2021/11/11 MySQL