Gearman分布式任务处理系统(五)通信协议

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 调用:

  1. X-Gearman-Unique:
  2. X-Gearman-Background: true
  3. 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服务内部的其它模块的调用。

相关文章
  1. gearman应用-分布式图库系统设计
  2. Gearman分布式任务处理系统(六)持久化存储
  3. Gearman-PHP扩展源码编译
  4. Gearman分布式任务处理系统(四)Gearmand源码编译
  5. Gearman分布式任务处理系统(三)分布式负载均衡架构
  6. Gearman分布式任务处理系统(二)Gearman工作流程细解
本站版权
1、本站所有主题由该文章作者发表,该文章作者与尘埃享有文章相关版权
2、其他单位或个人使用、转载或引用本文时必须同时征得该文章作者和尘埃的同意
3、本帖部分内容转载自其它媒体,但并不代表本站赞同其观点和对其真实性负责
4、如本帖侵犯到任何版权问题,请立即告知本站,本站将及时予与删除并致以最深的歉意
5、原文链接:
二维码
Posted in Gearman, linux技术
Comments are closed.