附件 Gearman.docphp
1:介绍gearmanlinux
Gearman是一个用来把工做委派给其余机器、分布式的调用更适合作某项工做的机器、并发的作某项工做在多个调用间作负载均衡、或用来在调用其它语言的函数的系统服务器
开源:Gearman免费而且开源并且有一个很是活跃的开源社区,若是你想来作一些贡献,请点击 。架构
多语言支持:Gearman支持的语言种类很是丰富。让咱们可以用一种语言来编写Worker程序,可是用另一种语言编写Client程序。并发
灵活:没必要拘泥于固定的形式。您能够采用你但愿的任何形式,例如 Map/Reduce。负载均衡
快速:Gearman的协议很是简单,而且有一个用C语言实现的,通过优化的服务器,保证应用的负载在很是低的水平。异步
可植入:由于Gearman很是小巧、灵活。所以您能够将他置入到现有的任何系统中。分布式
没有单点:Gearman不只能够帮助扩展系统,一样能够避免系统的失败函数
但有弊端就是占用系统资源较多,例如CPU、内存工具
将任务分发到多台服务器周期性的并发执
邮件短信发送
异步
跨语言相互调用(对于密集型计算的需求,能够用C实现,PHP直接调用)
典型架构:
一个Gearman请求的处理过程涉及三个角色:Client -> Job -> Worker。
Client:请求的发起者,能够是 C,PHP,Perl,MySQL UDF 等等。
Job:请求的调度者,用来负责协调把 Client 发出的请求转发给合适的 Worker。
Worker:请求的处理者,能够是 C,PHP,Perl 等等。
由于 Client,Worker 并不限制用同样的语言,因此有利于多语言多系统之间的集成。
甚至咱们经过增长更多的 Worker,能够很方便的实现应用程序的分布式负载均衡架构。
Gearman: https://launchpad.net/gearmand/1.2/1.1.2
Php扩展:http://pecl.php.net/get/gearman
基本面
基本的编辑步奏,若是编译有问题,按照
若是提示错误 按照提示相应的解决
编译完成以后:
gearmand -d
启动一个守护进程,gearmand –help 查看相关参数的用途
简单说明:
-d 守护进程模式
-L 监听 IP
-p 端口(7003为旧版本的默认端口,如今已经改成4730)
操做:
编译后生成 .so 文件 加入到ph.ini中 reload service
extension="gearman.so"
phpinfo() 查看是否开启该模块
Cli 下运行:
php worker.php&
phpclient.php
Gearman中Client和Job、Worker和Job之间的通信是经过TCP套接字数据包实现
Gearman中的消息是基于TCP的变长二进制消息:
请求和响应分别由Message Flag区分。这是一个4字节的结构。
Message Type目前共有36个,详细的定义可见http://gearman.org/index.php?id=protocol。它是一个4字节的big-endian的整形。
Data length定义了消息体的长度。它也是一个4字节的big-endian的整形。
消息体可由0-N个argument构成,argument间以’\0’分隔。长度是Data Length
不管是不是哪一种类型的 job,worker的工做流程都是同样的:
1.Worker经过CAN_DO消息,注册到Job server上。
2.随后发起GRAB_JOB,主动要求分派任务。
3.Job server若是没有job可分配,就返回NO_JOB。
4.Worker收到NO_JOB后,进入空闲状态,并给Job server返回PRE_SLEEP消息,告诉Job server:”若是有工做来的话,用NOOP请求我先。”
5.Job server收到worker的PRE_SLEEP消息后,明白了发送这条消息的worker已经进入了空闲态。
6.这时若是有job提交上来,Job server会给worker先发一个NOOP消息。
7.Worker收到NOOP消息后,发送GRAB_JOB向Job server请求任务。
8.Job server把工做派发给worker。
9.Worker干活,完过后返回WORK_COMPLETE给Job server。
值得注意的是,第6步中,Job server会给每一个发送过PRE_SLEEP消息的worker都发送NOOP 消息,哪一个worker先进入到第7步,即哪一个worker发送的GRAB_JOB最早被Job server收到,那么这个job就被派发到哪一个worker。这一点能够在worker端实现时利用起来,以控制任务的派发策略。也就是说,咱们能够经过自定义worker端的请求策略的方式来达到自定义job分派策略的目的
同步调用碰到的缺点:
• 每启动一个Work,Job服务器会自动建立一个Pid文件,这意味着他会占用文件打开句柄数
•当Client个数超过Worker个数的时候会出现排队现象,排队时会加长处理时间
•弥补方式,启动多个Woker迚程,如并发要求300那么启动150个Work
•形成后果,Worker空闲会致使闲置占用资源
•补救方式, –worker-wakeup 参数,指定唤醒多少个 Worker 进行处理。
•忽然发现个工具GearmanManager, 能够搞定上面事情~只要简单的使用便可
•传递的参数必须序列化
• Work占用必定内存和cpu,打开过多会占用不少资源非服务群使用效果不明显
异步调用的缺点:
•多个work处理log记录时,容易出现个别log乱序
•Work启动太少且工做时间太长会致使任务堆积,Job服务器占内存过多
•Work内调用的工做函数错误没法处理或通知,只能经过log查看结果
• 若是worker异常,没有接任务的worker很难发现,只能观察Job的持久服务器内的数据量
鉴于Gearman官网中说到,能够启动多个job服务器实例来保证job的自动故障转移功能,这样当一个job down后能够由另外一个job来处理,保证不间断的进行服务。我这里进行了测试,发现Gearman的确实现了自动故障转移功能,我这里的测试以下
1:启动两个虚拟机,分别为:
A:安装了PHP环境、Gearman job、Gearman PHP扩展;IP地址:192.168.213.184
B:只须要安装Gearman job;IP地址:192.168.213.185
2:两个虚拟机同时启动Gearman的Job服务器,以下:>./gearmand -d
3:在A虚拟机中编写worker.php,并运行worker实例,以下:
在以上的基础上,我使用kill -9命令随意关闭掉A、B虚拟机中的任意一个Job服务器,client.php都能正确运行,
说明当一台Job down时,服务仍然能继续进行,而且down的服务器重启后,就能够立刻继续服务,不须要任何额外的配置。