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环境搭建最新方法
Sep 05 PHP
在线增减.htpasswd内的用户
Oct 09 PHP
逐步提升php框架的性能
Jan 10 PHP
如何使用Linux的Crontab定时执行PHP脚本的方法
Dec 19 PHP
php setcookie(name, value, expires, path, domain, secure) 参数详解
Jun 28 PHP
PHP实现的sqlite数据库连接类
Dec 12 PHP
PHP新建类问题分析及解决思路
Nov 19 PHP
php使用Header函数,PHP_AUTH_PW和PHP_AUTH_USER做用户验证
May 04 PHP
PHP中获取文件创建日期、修改日期、访问时间的方法
Nov 05 PHP
php断点续传之文件分割合并详解
Dec 13 PHP
PHP使用strrev翻转中文乱码问题的解决方法
Jan 13 PHP
thinkphp框架无限级栏目的排序功能实现方法示例
Mar 29 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
SSI指令
2006/11/25 PHP
php中一个完整表单处理实现代码
2011/11/10 PHP
ThinkPHP的常用配置选项汇总
2016/03/24 PHP
限制复选框的最大可选数
2006/07/01 Javascript
jQuery chili图片远处放大插件
2009/11/30 Javascript
Javascript的闭包
2009/12/31 Javascript
MC Dialog js弹出层 完美兼容多浏览器(5.6更新)
2010/05/06 Javascript
解决JS请求服务器gbk文件乱码的问题
2015/10/16 Javascript
JavaScript前端开发之实现二进制读写操作
2015/11/04 Javascript
JS 获取HTML标签内的子节点的方法
2016/09/21 Javascript
详解如何较好的使用js
2016/12/16 Javascript
Node.js中多进程模块Cluster的介绍与使用
2017/05/27 Javascript
详解Chai.js断言库API中文文档
2018/01/31 Javascript
解决webpack无法通过IP地址访问localhost的问题
2018/02/22 Javascript
React 使用browserHistory项目访问404问题解决
2018/06/01 Javascript
[01:13]这,就是刀塔
2014/07/16 DOTA
python实现发送邮件及附件功能
2021/03/02 Python
Python二叉树的定义及常用遍历算法分析
2017/11/24 Python
Linux系统(CentOS)下python2.7.10安装
2018/09/26 Python
Python去除字符串前后空格的几种方法
2019/03/04 Python
python 图片二值化处理(处理后为纯黑白的图片)
2019/11/01 Python
Django配置文件代码说明
2019/12/04 Python
python如何从键盘获取输入实例
2020/06/18 Python
Python配置pip国内镜像源的实现
2020/08/20 Python
深入CSS3 动画效果的总结详解
2013/05/09 HTML / CSS
全球速卖通俄罗斯站:AliExpress俄罗斯
2019/06/17 全球购物
Lookfantastic俄罗斯:欧洲在线化妆品零售商
2019/08/06 全球购物
结构工程个人自荐信范文
2013/11/30 职场文书
金融学专科生自我鉴定
2014/02/21 职场文书
大学班级文化建设方案
2014/05/06 职场文书
优秀大学生自荐信
2014/06/09 职场文书
校园文明标语
2014/06/13 职场文书
施工安全协议书范本
2014/09/26 职场文书
放假通知范文
2015/04/14 职场文书
2015年计划生育协会工作总结
2015/05/13 职场文书
面试分析分布式架构Redis热点key大Value解决方案
2022/03/13 Redis