$GLOBALS 是一个关联数组,每一个变量为一个元素,键名对应变量名,值对应变量的内容。$GLOBALS 之所以在全局范围内存在,是因为 $GLOBALS 是一个超全局变量。 php语法中,很多人都认为global和$GLOBALS[]只是写法上面的差别,其实不然 根据官方的解释是 1. $GLOBALS['var']是外部的全局变量本身…
PHP: Gearman实现分布式处理, 分布式任务分发框架Gearman教程
一. 场景分析
业务服务压力比较大,想把一些占用资源的功能异步到远程处理,比如记录业务日志,文件加密,文件分发到其他文件服务器节点上,检查文件服务器是否已同步,对用户上传的图片进行剪裁生成多份缩略图,视频转换,静态内容生成,清除缓存等等,这些请求耗时长,占用系统资源大,影响业务正常访问。这些问题会经常遇到的,如果这些任务都在用户请求过程中完成,服务器撑不撑得住暂不考虑,单凭用户体验角度考虑来说,那是难以忍受的。
二. 解决之道
对于这种需求,我们可以通过分布式计算,对任务进行拆分,转移到多台服务器上进行异步或同步处理。分布式消息队列有多种实现方式如rabbitmq、gearman等。 在这里主要说gearman—分布式处理系统。gearman由三部分组成:Job server,worker server,client server。 任务服务器job server运行这gearmand进程,来负责处理应用的远程调用请求,并且维护计算任务;工作服务器worker server负责向job server注册函数等待领取任务并执行实际的计算,然后将结果返回给job server;客户端client server提供gearman client API给应用程序调用,API支持多种语言如C、php、perl、python、mysql udf、java、ruby、go等等,主要是向job server添加任务,
流程图如下:

通常,多语言多系统之间的集成是个大问题,一般来说,人们多半会采用WebService的方式来处理此类集成问题,但不管采用何种风格的WebService,如RPC风格,或者REST风格,其本身都有一定的复杂性。相比之下,Gearman也能实现类似的作用,而且更简单易用。
一个Gearman请求的处理过程涉及三个角色:Client -> Job -> Worker。
Client:请求的发起者,可以是C,PHP,Perl,MySQL UDF等等。
Job:请求的调度者,用来负责协调把Client发出的请求转发给合适的Work。
Worker:请求的处理者,可以是C,PHP,Perl等等。
因为Client,Worker并不限制用一样的语言,所以有利于多语言多系统之间的集成。
甚至我们通过增加更多的Worker,可以很方便的实现应用程序的分布式负载均衡架构。
客户端client server向gearman添加任务时,有三种模式:
1. 同步顺序处理 相当于消息队列,先进先出。
2. 同步并行处理 这种模式会阻塞后面的运行,将互不依赖的任务并行处理,大大缩短整体处理时间。
3. 异步后台处理 将耗时任务交给后台处理,不阻塞当前进程。
三. 应用实例
官网:http://gearman.org/download/
Job Server (gearmand) : https://github.com/gearman/gearmand/releases
Client & Worker APIs:https://launchpad.net/gearmand/
1. 安装Gearman server and library:
wget https://github.com/gearman/gearmand/releases/download/1.1.18/gearmand-1.1.18.tar.gz tar zxf gearmand-1.1.18.tar.gz cd gearmand-1.1.18 ./configure sudo make sudo make install
在./configure的时候,可能会出现缺少libraries的情况,一般是缺少libevent和uuid这两个开发包,安装之。。。
sudo apt-get install libevent-dev sudo apt-get install uuid-dev
安装完成后再重新配置安装,安装完成后执行
sudo ldconfig
2. Gearman Client和Worker端PHP实现实例,安装Gearman PHP extension:
wget http://pecl.php.net/get/gearman-1.0.2.tgz tar zxf gearman-1.0.2.tgz cd gearman-1.0.2 phpize ./configure sudo make sudo make install
中间可能遇到的问题:找不到phpize命令,phpize在php开发包中,所以要先安装php7-dev
sudo apt-get install php7dev
安装完后,就可以在源码目录中执行phpize生成相关安装配置信息,接着执行后面的./configure等make install后,它告诉你一个目录,生成的gearman.so就在那里。根据需要考到相应PHP的扩展目录里(因为我直接用系统默认安装的php,它自动生成就在扩展中) 接下来修改php.ini以使php加载该模块:可以通过(可以通过 php –ini 命令快速找到这个文件)
php --ini
看下php.ini在哪里,sudo vim 修改之,在其中加入
extension = "gearman.so"
保存此文件。要想验证扩展是否启用,请运行 php –info,然后查找 Gearman
$ php --info | grep "gearman support" gearman gearman support => enabled libgearman version => 1.1.18
此外,还可以用一个 PHP 代码片段来验证构建和安装是否得当。将这个小应用程序保存到 verify_gearman.php:
<?php print gearman_version() . "\n"; ?>
接下来,从命令行运行此程序:
$ php verify_gearman.php 1.1.18
如果这个版本号与之前构建和安装的 Gearman 库的版本号相匹配,那么系统就已准备好了。
然后,开始编写client和worker端:
client.php
<?php $client= new GearmanClient(); $client->addServer(); print $client->do("title", "AlL THE World's a sTagE"); print "\n"; ?>
从 PHP 使用 Gearman 类似于之前的示例,惟一的区别在于这里是在 PHP 内创建 producer 和 consumer。每个 consumer 的工作均封装在一个或多个 PHP 函数内。
worker.php
<?php $worker= new GearmanWorker(); $worker->addServer(); $worker->addFunction("title", "title_function"); while ($worker->work()); function title_function($job) { return ucwords(strtolower($job->workload())); } ?>
现在,可以用如下的命令行连接客户机与 worker 了:
1、启动job
gearmand -d
2、启动worker
php -c /etc/php5/apache2/php.ini worker.php
3、启动client(新开终端中打开)
php -c /etc/php5/apache2/php.ini client.php
屏幕显示字符串的长度 “5” 这里,有几点需要说明一下:
1、这里直接用php cli方式运行,添加-c参数是为了加载php.ini配置文件,以加载gearman扩展
2、worker应该做成守护进程(CLI模式),可以开启多个,这样client发起的任务就会分发到各个worker分别来执行(自动负载均衡 ) 这个例子由于太过简单,即使开启多个worker也无法看出效果,不过可以通过终止其中一个,可以看出系统自动切换到其他worker继续正常执行
3、同理,client也是可以开启多个的(模型请参考之前的那边日志)
4、同时,job也可以开启多个,以避免单点故障
或者:
$ php worker.php & $ php client.php All The World's A Stage $ jobs [3]+ Running php worker.php &
CHM手册: Gearman手册.zip
本文:PHP: Gearman实现分布式处理, 分布式任务分发框架Gearman教程