学而实习之 不亦乐乎

Gearman 介绍、原理分析

2023-12-27 20:52:38

一、Gearman 是什么?

Gearman 是一套用来把程式需求委派给机器,提供通用的程序框架来将任务分发在机器运算。它同时具备并行工作的能力、负载均衡处理的能力,以及在不同程序语言之间沟通的能力。

通常,多语言多系统之间的集成是个大问题,一般来说,人们多半会采用 WebService 的方式来处理此类集成问题,但不管采用何种风格的 WebService,如 RPC 风格,或者 REST 风格,其本身都有一定的复杂性。相比之下,Gearman 也能实现类似的作用,而且更简单易用。

Gearman 是分布式的程序调用框架,可完成跨语言的相互调用,适合在后台运行工作任务。最初是2005年perl版本,2008年发布C/C++版本。目前大部分源码都是(Gearmand服务job Server)C++,各个API实现有各种语言的版本。PHP的Client API与Worker API实现为C扩展,在PHP官方网站有此扩展的中英文文档。

gearman架构中的三个角色

  1. client:请求的发起者,工作任务的需求方(可以是C、PHP、Java、Perl、Mysql udf等等)
  2. Job Server:请求的调度者,负责将client的请求转发给相应的worker(gearmand服务进程创建)
  3. worker:请求的处理者(可以是C、PHP、Java、Perl等等)

二、Gearman 是如何工作的?

从上图可以看出,Gearman Client API,Gearman Worker API,Gearman Job Server都是由gearman本身提供,我们在应用中只需要调用即可。目前client与worker api都很丰富。

client.php

<?php

echo "starting...", microtime(true), "\n";
$gmc = new GearmanClient();
$gmc->setCompleteCallBack(function($task){
//echo $task->data(), "\n";
});

$gmc->addServer("127.0.0.1", 4730);
for ($i = 0; $i < 100000; $i++) {
     $gmc->addTaskBackground("reserve", "just test it", null, $i);
}

$gmc->runTasks();
echo "end...", microtime(true), "\n";

worker.php

<?php

$gmw = new GearmanWorker();
$gmw->addServer("127.0.0.1", 4730);
$gmw->addFunction("reserve", function($job) {
     if ($job->unique() == 99999) {
          echo microtime(true), "\n";
     }
     return strrev($job->workload());
});

while($gmw->work());

启动一个job server实例:job server IP:127.0.0.1 PORT:4730

启动一个worker: php worker.php

worker注册reserve函数,将client的job字符串反转后返回。

client工作任务的消息为:just test it(12字节)

出于方便的考虑,Worker,Client 使用的都是PHP,但这并不影响演示,实际应用中,你完全可以通过 Gearman 集成不同语言实现的 Worker,Client。或许此时你还想了解前面提到的负载均衡功能:很简单,只要增加多个 Worker 即可,你可以按照 worker.php 的样子多写几个类似的文件,并设置不同的返回值用以识别演示效果。然后依次启动这几个 Worker 文件,并多次使用 client.php 去请求,你就会发现 Job 会把 Client 请求转发给不同的 Worker。

三、Gearman 支持的特性:

1.高可用

启动两个job server,他们是独立的服务进程,有各自的内存队列。当一个job server进程出现故障,另一个job server可以正常调度。(worker api与client api可以完成job server故障的切换)。在任何时候我们可以关闭某个worker,即使那个worker正在处理工作任务(Gearman不会让正在被执行的job丢失的,由于worker在工作时与Job server是长连接,所以一旦worker发生异常,Job server能够迅速感知并重新派发这个异常worker刚才正在执行的工作)

2.负载均衡(附gearman协议会详细解释)

job server并不主动分派工作任务,而是由worker从空闲状态唤醒之后到job server主动抓取工作任务。

3.可扩展

松耦合的接口和无状态的job,只需要启动一个worker,注册到Job server集群即可。新加入的worker不会对现有系统有任何的影响。

4.分布式

gearman是分布式的任务分发框架,worker与job server,client与job server通信基于tcp的socket连接。

5.队列机制

gearman内置内存队列,默认情况队列最大容量为300W,可以配置最大支持2^32-1,即4 294 967 295。

6.高性能

作为Gearman的核心,Job server的是用C/C++实现的,由于只是做简单的任务派发,因此系统的瓶颈不会出在Job server上。

四、应用场景

  1. 结合linux crontab,php脚本负责产生job,将任务分发到多台服务器周期性的并发执行。可以取代目前我们比较多的crontab的工作任务。
  2. 邮件短信发送
  3. 异步log
  4. 跨语言相互调用(对于密集型计算的需求,可以用C实现,PHP直接调用)
  5. 其他耗时脚本