PS:Gearman工作在TCP上,默认端口为4730,client与job server、worker与job server的通信都基于此tcp的socket连接。client是工作任务的发起者,worker是可以注册处理函数的工作任务执行者,job server为工作的调度者。。
协议包含请求报文与响应报文两个部分,所有发向job server的数据包(TCP报文段的数据部分)认为是请求报文,所有从job server发出的数据包(TCP报文段的数据部分)认为是响应报文。worker或者client与job server间的通信是基于二进制数据流的,但在管理client也有基于行文本协议的通信。
请求的报文体
响应的报文体
请求报文与响应报文是由二进制包封装。一个二进制包由头header和可选的数据部分data组成。
header的组成
a.报文类别,请求报文或者响应报文,4个字节
“\0REQ” 请求报文
“\0RES” 响应报文
b.包类型,高(大)字节序(网络字节序),4个字节可能的类型有
类型值 名称 报文类型 发送者 1 CAN_DO REQ Worker 2 CANT_DO REQ Worker 3 RESET_ABILITIES REQ Worker 4 PRE_SLEEP REQ Worker 5 (unused) - - 6 NOOP RES Worker 7 SUBMIT_JOB REQ Client 8 JOB_CREATED RES Client 9 GRAB_JOB REQ Worker 10 NO_JOB RES Worker 11 JOB_ASSIGN RES Worker 12 WORK_STATUS REQ Worker 13 WORK_COMPLETE REQ Worker 14 WORK_FAIL REQ Worker 15 GET_STATUS REQ Client 16 ECHO_REQ REQ Client/Worker 17 ECHO_RES RES Client/Worker 18 SUBMIT_JOB_BG REQ Client 19 ERROR RES Client/Worker 20 STATUS_RES RES Client 21 SUBMIT_JOB_HIGH REQ Client 22 SET_CLIENT_ID REQ Worker 23 CAN_DO_TIMEOUT REQ Worker 24 ALL_YOURS REQ Worker 25 WORK_EXCEPTION REQ Worker 26 OPTION_REQ REQ Client/Worker 27 OPTION_RES RES Client/Worker 28 WORK_DATA REQ Worker 29 WORK_WARNING REQ Worker 30 GRAB_JOB_UNIQ REQ Worker 31 JOB_ASSIGN_UNIQ RES Worker 32 SUBMIT_JOB_HIGH_BG REQ Client 33 SUBMIT_JOB_LOW REQ Client 34 SUBMIT_JOB_LOW_BG REQ Client 35 SUBMIT_JOB_SCHED REQ Client 36 SUBMIT_JOB_EPOCH REQ Client
c.可选数据部分长度,高(大)字节序(网络字节序),4个字节,可表示的值为4294967295数据部分,数据部分的各个部分为null字符分隔。
具体各包类型的说明
client和worker都可以发送的请求报文:
ECHO_REQ
当job server收到此包类型的请求报文时,就简单的产生一个包类型为ECHO_RES,同时将请求报文的数据部分作为响应报文的数据部分的报文。主要用于测试或者调试
如:
Client -> Job Server 00 52 45 51 \0REQ 报文类型 00 00 00 a0 16 (Packet type: ECHO_ERQ) 00 00 00 04 4 (Packet length) 74 65 73 74 test (Workload)
client和worker都可以接收的响应报文:
ECHO_RES
当job server响应ECHO_REQ报文时发送的包类型为ECHO_RES的响应报文,如:
Job Server -> Client 00 52 45 53 \0RES 报文类型 00 00 00 a1 17 (Packet type: ECHO_ERS) 00 00 00 04 4 (Packet length) 74 65 73 74 test (Workload)
ERROR
当job server发生错误时,需要通知client或者worker
client发送的请求报文:(仅能由client发送的请求报文)
SUBMIT_JOB, SUBMIT_JOB_BG,SUBMIT_JOB_HIGH, SUBMIT_JOB_HIGH_BG,SUBMIT_JOB_LOW, SUBMIT_JOB_LOW_BG
当client有一个工作任务需要运行,就会提交相应的请求报文,job server响应包类型为JOB_CREATED数据部分为job handle的响应报文。SUBMIT_JOB为普通的工作任务,client得到状态更新及通知任务已经完成的响应;SUBMIT_JOB_BG为异步的工作任务,client不关心任务的完成情况;SUBMIT_JOB_HIGH为高优先级的工作任务,SUBMIT_JOB_HIGH_BG为高优先级的异步任务;SUBMIT_JOB_LOW为低优先级的工作任务,SUBMIT_JOB_LOW_BG为低优先级的异步任务。
如:
Client -> Job Server 00 52 45 51 \0REQ (报文类型) 00 00 00 07 7 (Packet type: SUBMIT_JOB) 00 00 00 0d 13 (Packet length) 72 65 76 65 72 73 65 00 reverse\0 (Function) 00 \0 (Unique ID) 74 65 73 74 test (Workload)
SUBMIT_JOB_SCHED
和SUBMIT_JOB_BG类似,此类型的工作任务不会立即执行,而在设置的某个时间运行。
如:
Client -> Job Server 00 52 45 51 \0REQ (报文类型) 00 00 00 23 35 (Packet type: SUBMIT_JOB_SCHED) 00 00 00 0d 13 (Packet length) 72 65 76 65 72 73 65 00 reverse\0 (Function) 00 \0 (Unique ID) 01 \0 (minute 0-59) 01 \0 (hour 0-23) 01 \0 (day of month 1-31) 01 \0 (day of month 1-12) 01 \0 (day of week 0-6) 74 65 73 74 test (Workload)
SUBMIT_JOB_EPOCH
和SUBMIT_JOB_SCHED作用一样,只是将设置的时间定为了uinx时间戳GET_STATUS获取某个工作任务执行的状态信息
OPTION_REQ
设置client与job server连接的选项
client获取的响应报文:
JOB_CREATED响应包类型为SUBMIT_JOB*的请求报文,数据部分为job handle
WORK_DATA, WORK_WARNING, WORK_STATUS, WORK_COMPLETE,WORK_FAIL, WORK_EXCEPTION
对于后台运行的工作任务,任务执行信息可以通过包类型为上面的值来查看。
STATUS_RES:响应包类型为GET_STATUS的请求报文,通常用来查看一个后台工作任务是否已经完成,以及完成的百分比。
OPTION_RES:响应包类型为OPTION_REQ的请求报文
worker发送的请求报文:
CAN_DO:通知job server可以执行给定的function name的任务,此worker将会放到一个链表,当job server收到一个function name的工作任务时,worker为被唤醒。
CAN_DO_TIMEOUT:和CAN_DO类似,只是针对给定的function_name的任务设置了一个超时时间。
CANT_DO:worker通知job server已经不能执行给定的function name的任务
RESET_ABILITIES:worker通知job server不能执行任何function name的任务
PRE_SLEEP:worker通知job server它将进入sleep阶段,而之后此worker会被包类型为NOOP的响应报文唤醒。
GRAB_JOB:worker向job server抓取工作任务,job server将会响应NO_JOB或者JOB_ASSIG
NGRAB_JOB_UNIQ:和GRAB_JOB类似,但是job server在有工作任务时将会响应JOB_ASSIGN_UNIQ
WORK_DATA:worker请求报文的数据部分更新client
WORK_WARNING:worker请求报文代表一个warning,它应该被对待为一个WARNING
WORK_STATU:Sworker更新某个job handle的工作状态,job server应该储存这些信息,以便响应之后client的GET_STATUS请求
WORK_COMPLETE:通知job server及所有连接的client,数据部分为返回给client的数据
WORK_FAIL:通知job server及所有连接的client,工作任务执行失败
WORK_EXCEPTION:通知job server及所有连接的client,工作任务执行失败并给出相应的异常
SET_CLIENT_ID:设置worker ID,从而job server的控制台及报告命令可以标识各个worker,数据部分为worker实例的标识
ALL_YOURS:暂未实现
worker获取的响应报文:
NOOP:job server唤醒sleep的worker,以便可以开始抓取工作任务
NO_JOB:job server响应GRAB_JOB的请求,通知worker没有等待执行的工作任务
JOB_ASSIGN:job server响应GRAB_JOB的请求,通知worker有需要执行的工作任务
JOB_ASSIGN_UNIQ:job server响应GRAB_JOB_UNIQ的请求,和JOB_ASSIGN一样,只是为client传递了一个唯一标识
基于上述的协议描述一个完整的例子
worker注册可以执行的工作任务
Worker -> Job Server 00 52 45 51 \0REQ (Magic) 00 00 00 01 1 (Packet type: CAN_DO) 00 00 00 07 7 (Packet length) 72 65 76 65 72 73 65 reverse (Function)
worker检测或者抓取工作任务
Worker -> Job Server 00 52 45 51 \0REQ (Magic) 00 00 00 09 9 (Packet type: GRAB_JOB) 00 00 00 00 0 (Packet length)
job server响应worker的抓取工作(没有工作任务)
00 52 45 53 \0RES (Magic) 00 00 00 0a 10 (Packet type: NO_JOB) 00 00 00 00 0 (Packet length)
worker通知job server开始sleep
00 52 45 51 \0REQ (Magic) 00 00 00 04 4 (Packet type: PRE_SLEEP) 00 00 00 00 0 (Packet length)
client提交工作任务
Client -> Job Server 00 52 45 51 \0REQ (Magic) 00 00 00 07 7 (Packet type: SUBMIT_JOB) 00 00 00 0d 13 (Packet length) 72 65 76 65 72 73 65 00 reverse\0 (Function) 00 \0 (Unique ID) 74 65 73 74 test (Workload)
job server响应client的SUBMIT_JOB请求,返回job handle
00 52 45 53 \0RES (Magic) 00 00 00 08 8 (Packet type: JOB_CREATED) 00 00 00 07 7 (Packet length) 48 3a 6c 61 70 3a 31 H:lap:1 (Job handle)
job server唤醒worker
Job Server -> Worker 00 52 45 53 \0RES (Magic) 00 00 00 06 6 (Packet type: NOOP) 00 00 00 00 0 (Packet length)
worker的抓取工作任务
Worker -> Job Server 00 52 45 51 \0REQ (Magic) 00 00 00 09 9 (Packet type: GRAB_JOB) 00 00 00 00 0 (Packet length)
job server分配工作任务给worker
Job Server -> Worker 00 52 45 53 \0RES (Magic) 00 00 00 0b 11 (Packet type: JOB_ASSIGN) 00 00 00 14 20 (Packet length) 48 3a 6c 61 70 3a 31 00 H:lap:1\0 (Job handle) 72 65 76 65 72 73 65 00 reverse\0 (Function) 74 65 73 74 test (Workload)
worker完成工作任务通知job server
00 52 45 51 \0REQ (Magic) 00 00 00 0d 13 (Packet type: WORK_COMPLETE) 00 00 00 0c 12 (Packet length) 48 3a 6c 61 70 3a 31 00 H:lap:1\0 (Job handle) 74 73 65 74 tset (Response)
job server通知client完成了工作任务
Job Server -> Client 00 52 45 53 \0RES (Magic) 00 00 00 0d 13 (Packet type: WORK_COMPLETE) 00 00 00 0c 12 (Packet length) 48 3a 6c 61 70 3a 31 00 H:lap:1\0 (Job handle) 74 73 65 74 tset (Response)
每个client与job server是全双工通信,在一个socket可以完成多个工作任务的投递,但是收到任务的执行结果的顺序可能与投递的顺序不一致。
总结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
扩展协议
在 0.8 的版本的时候, 这个 Gearman job server 加入了协议的插件支持.第一个支持的是原生的 HTTP 来使用 Gearman protocol. 这个协议的接口可以接收的 send 和 recieve 功能.核心的读和写的功能可以使用这个协议插件来支持.
HTTP
协议插件是给 HTTP 请求映射成 Gearman 的任务.它当前只支持 client 任务的提交,但它可能在未来进行扩展以支持其他类型的请求. 这个插件可以使用 GET and POST 来提交, 然后会给这些任务放入给 job server.这个 URL 的请求会被转成功能的调用.象下面这个例子的请求:
#POST请求 POST /reverse HTTP/1.1 Content-Length: 12 Hello world!
上面这个会给使用 “reverse”这个function,workload为 “Hello world!”的参数. 这会返回:
HTTP/1.0 200 OK X-Gearman-Job-Handle: H:lap:4 Content-Length: 12 Server: Gearman/0.8 !dlrow olleH
下面的这些 header 可以传送过去来做为高级的 job 调用:
- X-Gearman-Unique:
- X-Gearman-Background: true
- X-Gearman-Priority:
象这下面这个的例子中, 它运行在低级别的后台作业,只需要象这样发送请求:
POST /reverse HTTP/1.1 Content-Length: 12 X-Gearman-Background: true X-Gearman-Priority: low Hello world!
这个请求的响应将不会有任何数据,因为它是一个后台作业:
HTTP/1.0 200 OK X-Gearman-Job-Handle: H:lap:6 Content-Length: 0 Server: Gearman/0.8
应用场景:
开启gearman http监听功能,让前端以web api方式调用gearman job
起用方式:
在gearmand的起动参数中加上:
/usr/local/gearman/sbin/gearmand \ -l /usr/local/gearman/log/trace.log \ --verbose INFO -p 4730 -u root -d -t 4 \ -r http --http-port=8080 \ #--http-port=8080 指定监听端口号 #-r http 起用http协议模块
调用方式:
目前http协议只支持任务提交类接口,其它类型的暂不支持。
按官方文档上说,http支持GET和POS两种方式调用,但是GET方式我还没弄清楚怎样携带数据,POST方式实验过是可以的
http://192.168.1.1:8080/reverse
reverse就为函数名,假如POST的数据内容为:“Hello world!”,返回结果为:“!dlrow olleH”
在http的header头中可以设置一些任务参数:
X-Gearman-Unique:
X-Gearman-Background: true
X-Gearman-Priority:
这种使用方式,实际上gearmand监听着两个端,原来的4730端还是可以接收正常的gearman协议客户端的请求,另外的8080端口则监听着http协议的请求,两种方式共同工作,http服务前端如移动端调用,gearman服务内部的其它模块的调用。