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往windows中添加用户
Dec 06 PHP
php 图片上传类代码
Jul 17 PHP
PHP执行linux系统命令的常用函数使用说明
Apr 27 PHP
php面向对象中的魔术方法中文说明
Mar 04 PHP
php去除换行(回车换行)的三种方法
Mar 26 PHP
10条php编程小技巧
Jul 07 PHP
WordPress中用于检索模版的相关PHP函数使用解析
Dec 15 PHP
基于ThinkPHP实现的日历功能实例详解
Apr 15 PHP
自制PHP框架之路由与控制器
May 07 PHP
PHP实现的mysql主从数据库状态检测功能示例
Jul 20 PHP
基于Laravel-admin 后台的自定义页面用法详解
Sep 30 PHP
laravel 多图上传及图片的存储例子
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自带的进位制之间的转换函数
2013/06/08 PHP
php写入数据到CSV文件的方法
2015/03/14 PHP
PHP实现搜索地理位置及计算两点地理位置间距离的实例
2016/01/08 PHP
php基于自定义函数记录log日志方法
2017/07/21 PHP
PHP中使用jQuery+Ajax实现分页查询多功能操作(示例讲解)
2017/09/17 PHP
PHP使用mysqli同时执行多条sql查询语句的实例
2019/03/22 PHP
javascript实现json页面分页实例代码
2014/02/20 Javascript
百度地图API之本地搜索与范围搜索
2015/07/30 Javascript
JS实现网页上随滚动条滚动的层效果代码
2015/11/04 Javascript
深入理解JavaScript内置函数
2016/06/03 Javascript
connection reset by peer问题总结及解决方案
2016/10/21 Javascript
Bootstrap中glyphicons-halflings-regular.woff字体报404错notfound的解决方法
2017/01/19 Javascript
jQuery Masonry瀑布流布局神器使用详解
2017/05/25 jQuery
原生js+cookie实现购物车功能的方法分析
2017/12/21 Javascript
30分钟精通React今年最劲爆的新特性——React Hooks
2019/03/11 Javascript
浅谈js中的bind
2019/03/18 Javascript
用Node写一条配置环境的指令
2019/11/14 Javascript
js实现简单的无缝轮播效果
2020/09/05 Javascript
vue 数据双向绑定的实现方法
2021/03/04 Vue.js
[02:26]DOTA2英雄米拉娜基础教程
2013/11/25 DOTA
《Python学习手册》学习总结
2018/01/17 Python
使用Python批量修改文件名的代码实例
2019/01/24 Python
Django中的cookie和session
2019/08/27 Python
CSS3下的渐变文字效果实现示例
2018/03/02 HTML / CSS
美国职棒大联盟官方网上商店:MLBShop.com
2017/11/12 全球购物
Quiksilver美国官网:始于1969年的优质冲浪服和滑雪板外套
2020/04/20 全球购物
直接有效的自我评价
2014/01/11 职场文书
六年级学生评语
2014/04/22 职场文书
八年级英语教学计划
2015/01/23 职场文书
2015年度销售个人工作总结
2015/03/31 职场文书
校园广播站开场白
2015/06/01 职场文书
有关三国演义的读书笔记
2015/06/25 职场文书
幼儿园中班班级总结
2015/08/10 职场文书
运动会口号霸气押韵
2015/12/24 职场文书
python 如何用terminal输入参数
2021/05/25 Python
Python Pandas pandas.read_sql函数实例用法
2021/06/21 Python