我们项目使用了gearman来处理异步任务,效果不错,最近在做一些优化,看到底层server的代码,搜了一下发现网上有一篇写的很好。重点看后面的原理分析。
gearman是什么?
它是分布式的程序调用框架,可完成跨语言的相互调用,适合在后台运行工作任务。最初是2005年perl版本,2008年发布C/C++版本。目前大部分源码都是(Gearmand服务job Server)C++,各个API实现有各种语言的版本。PHP的Client API与Worker API实现为C扩展,在PHP官方网站有此扩展的中英文文档。
gearman架构中的三个角色
client:请求的发起者,工作任务的需求方(可以是C、PHP、Java、Perl、Mysql udf等等)
Job Server:请求的调度者,负责将client的请求转发给相应的worker(gearmand服务进程创建)
worker:请求的处理者(可以是C、PHP、Java、Perl等等)
gearman是如何工作的?
从上图可以看出,Gearman Client API,Gearman Worker API,Gearman Job Server都是由gearman本身提供,我们在应用中只需要调用即可。目前client与worker api都很丰富。
gearman的吞吐能力
经过的测试,结果如下:
系统环境:ubuntu-14.0.4 1个CPU 4核 2G内存 (虚拟机)
默认启动:./gearmand -d
client.php
1 | <?php |
2 | echo "starting..." , microtime(true), "\n" ; |
3 | $gmc = new GearmanClient(); |
4 | $gmc ->setCompleteCallBack( function ( $task ){ |
5 | //echo $task->data(), "\n"; |
6 | }); |
7 | $gmc ->addServer( "127.0.0.1" , 4730); |
8 | for ( $i = 0; $i < 100000; $i ++) { |
9 | $gmc ->addTaskBackground( "reserve" , "just test it" , null, $i ); |
10 | } |
11 | $gmc ->runTasks(); |
12 | echo "end..." , microtime(true), "\n" ; |
worker.php
1 | <?php |
2 | $gmw = new GearmanWorker(); |
3 | $gmw ->addServer( "127.0.0.1" , 4730); |
4 | $gmw ->addFunction( "reserve" , function ( $job ) { |
5 | if ( $job ->unique() == 99999) { |
6 | echo microtime(true), "\n" ; |
7 | } |
8 | return strrev ( $job ->workload()); |
9 | }); |
10 | 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字节)
同步:4100/s异步:25700/s
memcached内存准持久化的吞吐能力测试./gearmand -d -q libmemcached --libmemcached-servers=127.0.0.1:11211
client投递100000个工作任务:16400/s
gearman典型的部署结构
从上图可以看出,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上。
两种工作任务
后台工作任务Background job——时序图
由图可知,client提交完job,job