gearman(異步計(jì)算)學(xué)習(xí)
Gearman是什么?
它是分布式的程序調(diào)用框架,可完成跨語言的相互調(diào) 用,適合在后臺運(yùn)行工作任務(wù)。最初是2005年perl版本,2008年發(fā)布C/C++版本。目前大部分源碼都是(Gearmand服務(wù)job Server)C++,各個API實(shí)現(xiàn)有各種語言的版本。PHP的Client API與Worker API實(shí)現(xiàn)為C擴(kuò)展,在PHP官方網(wǎng)站有此擴(kuò)展的中英文文檔。
2Gearman架構(gòu)中的三個角色
client:請求的發(fā)起者,工作任務(wù)的需求方(可以是C、PHP、Java、Perl、Mysql udf等等)
Job Server:請求的調(diào)度者,負(fù)責(zé)將client的請求轉(zhuǎn)發(fā)給相應(yīng)的worker(gearmand服務(wù)進(jìn)程創(chuàng)建)
worker:請求的處理者(可以是C、PHP、Java、Perl等等)
Gearman是如何工作的?

從上圖可以看出,Gearman Client API,Gearman Worker API,Gearman Job Server都是由gearman本身提供,我們在應(yīng)用中只需要調(diào)用即可。目前client與worker api都很豐富。
3Gearman的吞吐能力
經(jīng)過的測試,結(jié)果如下:
系統(tǒng)環(huán)境:ubuntu-14.0.4 1個CPU 4核 2G內(nèi)存 (虛擬機(jī))
默認(rèn)啟動:./gearmand -d
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實(shí)例:job server IP:127.0.0.1 PORT:4730
啟動一個worker: php worker.php
worker注冊reserve函數(shù),將client的job字符串反轉(zhuǎn)后返回。
client工作任務(wù)的消息為:just test it(12字節(jié))
同步:4100/s
異步:25700/s
memcached內(nèi)存準(zhǔn)持久化的吞吐能力測試
./gearmand -d -q libmemcached —libmemcached-servers=127.0.0.1:11211
client投遞100000個工作任務(wù):16400/s
Gearman典型的部署結(jié)構(gòu)

Gearman支持的特性
高可用
啟動兩個job server,他們是獨(dú)立的服務(wù)進(jìn)程,有各自的內(nèi)存隊(duì)列。當(dāng)一個job server進(jìn)程出現(xiàn)故障,另一個job server可以正常調(diào)度。(worker api與client api可以完成job server故障的切換)。在任何時候我們可以關(guān)閉某個worker,即使那個worker正在處理工作任務(wù)(Gearman不會讓正在被執(zhí)行的job丟失的,由于worker在工作時與Job server是長連接,所以一旦worker發(fā)生異常,Job server能夠迅速感知并重新派發(fā)這個異常worker剛才正在執(zhí)行的工作)
負(fù)載均衡(附gearman協(xié)議會詳細(xì)解釋)
job server并不主動分派工作任務(wù),而是由worker從空閑狀態(tài)喚醒之后到j(luò)ob server主動抓取工作任務(wù)。
可擴(kuò)展
松耦合的接口和無狀態(tài)的job,只需要啟動一個worker,注冊到Job server集群即可。新加入的worker不會對現(xiàn)有系統(tǒng)有任何的影響。
分布式
gearman是分布式的任務(wù)分發(fā)框架,worker與job server,client與job server通信基于tcp的socket連接。
隊(duì)列機(jī)制
gearman內(nèi)置內(nèi)存隊(duì)列,默認(rèn)情況隊(duì)列最大容量為300W,可以配置最大支持2^32-1,即4 294 967 295。
高性能
作為Gearman的核心,Job server的是用C/C++實(shí)現(xiàn)的,由于只是做簡單的任務(wù)派發(fā),因此系統(tǒng)的瓶頸不會出在Job server上。
兩種工作任務(wù)
后臺工作任務(wù)Background job——時序圖

由圖可知,client提交完job,job server成功接收后返回JOB_CREATED響應(yīng)之后,client就斷開與job server之間的鏈接了。后續(xù)無論發(fā)生什么事情,client都是不關(guān)心的。同樣,job的執(zhí)行結(jié)果client端也沒辦法通過Gearman消息框架 獲得。
一般工作任務(wù)Non-background job——時序圖

由圖可知,client端在job執(zhí)行的整個過程中,與job server端的鏈接都是保持著的,這也給job完成后job server返回執(zhí)行結(jié)果給client提供了通路。同時,在job執(zhí)行過程當(dāng)中,client端還可以發(fā)起job status的查詢。當(dāng)然,這需要worker端的支持的。
4關(guān)于持久化
對于隊(duì)列持久化的問題,是一個值得考慮的問題。持久化必然影響高性能。gearman支持后臺工作任務(wù)的持久化,支持drizzle、mysql、memcached的持久化。對于client提交的background job,Job server除了將其放在內(nèi)存隊(duì)列中進(jìn)行派發(fā)之外,還會將其持久化到外部的持久化隊(duì)列中。一旦Job server發(fā)生問題重啟,外部持久化隊(duì)列中的background job將會被恢復(fù)到內(nèi)存中,參與Job server新的派發(fā)當(dāng)中。這保證了已提交未執(zhí)行的background job不會由于Job server發(fā)生異常而丟失。并且我測試發(fā)現(xiàn)如果開啟了持久化,那么后臺工作任務(wù)會先將工作任務(wù)寫到持久化介質(zhì),然后在入內(nèi)存隊(duì)列,再執(zhí)行。非后臺工作任務(wù),由于client與job server是保持長連接的狀態(tài),如果工作任務(wù)執(zhí)行異常,client可以靈活處理,所以無須持久化。
Gearman框架中的一個問題
從典型部署結(jié)構(gòu)看出,兩個Job server之間是沒有連接的。也就是Job server間是不共享background job的。如果通過讓兩個Job server指向同一個持久化隊(duì)列,可以讓兩個Job serer互相備份。但實(shí)際上,這樣是行不通的。因?yàn)镴ob server只有在啟動時才會將持久化隊(duì)列中的background job轉(zhuǎn)入到內(nèi)存隊(duì)列。也就是說,Job server1如果宕機(jī)且永遠(yuǎn)不啟動,Job server2一直正常運(yùn)行,那么Job server1宕機(jī)前被提交到Job server1的未被執(zhí)行的background job將永遠(yuǎn)都呆在持久化隊(duì)列中,得不到執(zhí)行。另外如果多個job server實(shí)例指向同一個持久化隊(duì)列,同時重啟多個job server實(shí)例會導(dǎo)致持久隊(duì)列中的工作任務(wù)被多次載入,從而導(dǎo)致消息重復(fù)處理。
我建議的部署結(jié)構(gòu)

采用memcached做后臺工作任務(wù)的準(zhǔn)持久化隊(duì)列,最好memcached和job server在內(nèi)網(wǎng)的不同機(jī)器。兩個機(jī)器的兩個服務(wù)同時掛掉的可能性比較小,同時也保證了高性能。而且memcached應(yīng)該為兩個相互獨(dú)立實(shí)例,防止其上述的gearman框架中的問題。我們可以做一個監(jiān)控腳本,如果某個job server異常退出,可以重啟,也最大化的保證了job server的高可用。
5關(guān)于Gearman的管理工具
目前有一個現(xiàn)在的管理工具,https://github.com/brianlmoon/GearmanManager,但是只支持php-5.2,不過可以自行修改支持php-5.4,我建議如果使用PHP作為worker進(jìn)程,使用php-5.4以上的版本。該工具的設(shè)計(jì)方法可以借鑒,可以比較好的管理gearman worker。
應(yīng)用場景
-
結(jié)合linux crontab,php腳本負(fù)責(zé)產(chǎn)生job,將任務(wù)分發(fā)到多臺服務(wù)器周期性的并發(fā)執(zhí)行??梢匀〈壳拔覀儽容^多的crontab的工作任務(wù)。
-
郵件短信發(fā)送
-
異步log
-
跨語言相互調(diào)用(對于密集型計(jì)算的需求,可以用C實(shí)現(xiàn),PHP直接調(diào)用)
-
其他耗時腳本
Gearman安裝(unbuntu)
下載
$>wget https://launchpadlibrarian.net/165674261/gearmand-1.1.12.tar.gz |
安裝依賴包
$>sudo apt-get install libboost1.55-all-dev gperf libevent libevent-dev uuid libmemcached-dev
$>tar zxvf gearmand-1.1.12.tar.gz
$>cd gearmand-1.1.12
$>/configure --prefix=/home/phpboy/Server/gearman
$>make & make install
啟動
a)默認(rèn)啟動
$>./gearman -d |
b)支持memcached準(zhǔn)持久化
$>./gearmand -d -q libmemcached --libmemcached-servers=127.0.0.1:11211
安裝php的Gearman擴(kuò)展
$>wget http://pecl.php.net/get/gearman-1.1.2.tgz
$>tar zxvf gearman-1.1.2.tgz#cd gearman-1.1.2
$>phpize
$>./configure --with-php-config=php-config
$>make & make install
php client api與php worker api
可以用上面我的測試的示例
附Gearmand(job server的啟動參數(shù)簡單說明)
-b, –backlog=BACKLOG 連接請求隊(duì)列的最大值
-d, –daemon Daemon 守護(hù)進(jìn)程化
-f, –file-descriptors=FDS 可打開的文件描述符數(shù)量
-h, –help
-l, –log-file=FILE Log 日志文件
-L, –listen=ADDRESS 開啟監(jiān)聽的地址
-p, –port=PORT 開啟監(jiān)聽的端口
-P, –pid-file=FILE File pid file
-r,–protocol=PROTOCOL 使用的協(xié)議
-q, –queue-type=QUEUE 持久化隊(duì)列類型
-t, –threads=THREADS I/O線程數(shù)量
-u, –user=USER 進(jìn)程的有效用戶名
libdrizzle Options:
--libdrizzle-host=HOST Host of server.
--libdrizzle-port=PORT Port of server.
--libdrizzle-uds=UDS Unix domain socket for server.
--libdrizzle-user=USER User name for authentication.
--libdrizzle-password=PASSWORD Password for authentication.
--libdrizzle-db=DB Database to use.
--libdrizzle-table=TABLE Table to use.
--libdrizzle-mysql Use MySQL protocol.
libmemcached Options:
--libmemcached-servers=SERVER_LIST List of Memcached servers to use.
libsqlite3 Options:
--libsqlite3-db=DB Database file to use.
--libsqlite3-table=TABLE Table to use.
libpq Options:
--libpq-conninfo=STRING PostgreSQL connection information string.
--libpq-table=TABLE Table to use.
http Options:
--http-port=PORT Port to listen on.
Gearman通信協(xié)議
總括
Gearman工作在TCP上,默認(rèn)端口為4730,client與job server、worker與job server的通信都基于此tcp的socket連接。client是工作任務(wù)的發(fā)起者,worker是可以注冊處理函數(shù)的工作任務(wù)執(zhí)行者,job server為工作的調(diào)度者。協(xié)議包含請求報文與響應(yīng)報文兩個部分,所有發(fā)向job server的數(shù)據(jù)包(TCP報文段的數(shù)據(jù)部分)認(rèn)為是請求報文,所有從job server發(fā)出的數(shù)據(jù)包(TCP報文段的數(shù)據(jù)部分)認(rèn)為是響應(yīng)報文。worker或者client與job server間的通信是基于二進(jìn)制數(shù)據(jù)流的,但在管理client也有基于行文本協(xié)議的通信。
請求的報文體

響應(yīng)的報文體

后臺工作任務(wù)Background job

一般工作任務(wù)Non-background job

二進(jìn)制包
請求報文與響應(yīng)報文是由二進(jìn)制包封裝。一個二進(jìn)制包由頭header和可選的數(shù)據(jù)部分data組成。
header的組成
-
報文類別,請求報文或者響應(yīng)報文,4個字節(jié)
“?REQ” 請求報文
“?RES” 響應(yīng)報文 -
包類型,高(大)字節(jié)序(網(wǎng)絡(luò)字節(jié)序),4個字節(jié)可能的類型有
類型值 名稱 報文類型 發(fā)送者
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
- 可選數(shù)據(jù)部分長度,高(大)字節(jié)序(網(wǎng)絡(luò)字節(jié)序),4個字節(jié),可表示的值為4294967295
數(shù)據(jù)部分,數(shù)據(jù)部分的各個部分為null字符分隔。
具體各包類型的說明
client和worker可發(fā)送請求報文
ECHO_REQ
當(dāng)job server收到此包類型的請求報文時,就簡單的產(chǎn)生一個包類型為ECHO_RES,同時將請求報文的數(shù)據(jù)部分作為響應(yīng)報文的數(shù)據(jù)部分的報文。主要用于測試或者調(diào)試
如:
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)
ECHO_RESclient和worker可接收響應(yīng)報文
當(dāng)job server響應(yīng)ECHO_REQ報文時發(fā)送的包類型為ECHO_RES的響應(yīng)報文
如:
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)
當(dāng)job server發(fā)生錯誤時,需要通知client或者workerERROR
client發(fā)送的請求報文:(僅能由client發(fā)送的請求報文)
SUBMIT_JOB, SUBMIT_JOB_BG,SUBMIT_JOB_HIGH, SUBMIT_JOB_HIGH_BG,SUBMIT_JOB_LOW, SUBMIT_JOB_LOW_BG
當(dāng)client有一個工作任務(wù)需要運(yùn)行,就會提交相應(yīng)的請求報文,job server響應(yīng)包類型為JOB_CREATED數(shù)據(jù)部分為job handle的響應(yīng)報文。SUBMIT_JOB為普通的工作任務(wù),client得到狀態(tài)更新及通知任務(wù)已經(jīng)完成的響應(yīng);SUBMIT_JOB_BG為異步的工作任務(wù),client不關(guān)心任務(wù)的完成情況;SUBMIT_JOB_HIGH為高優(yōu)先級的工作任務(wù),SUBMIT_JOB_HIGH_BG為高優(yōu)先級的異步任務(wù);SUBMIT_JOB_LOW為低優(yōu)先級的工作任務(wù),SUBMIT_JOB_LOW_BG為低優(yōu)先級的異步任務(wù)。
如:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
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 reverse0 (Function) 00 ? (Unique ID) 74 65 73 74 test (Workload) |
SUBMIT_JOB_SCHED
和SUBMIT_JOB_BG類似,此類型的工作任務(wù)不會立即執(zhí)行,而在設(shè)置的某個時間運(yùn)行。
如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
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 reverse0 (Function) 00 ? (Unique ID) 01 ? (minute 0-59) 01 ? (hour 0-23) 01 ? (day of month 1-31) 01 ? (day of month 1-12) 01 ? (day of week 0-6) 74 65 73 74 test (Workload) |
SUBMIT_JOB_EPOCH
和SUBMIT_JOB_SCHED作用一樣,只是將設(shè)置的時間定為了uinx時間戳GET_STATUS獲取某個工作任務(wù)執(zhí)行的狀態(tài)信息
OPTION_REQ
設(shè)置client與job server連接的選項(xiàng)
client獲取的響應(yīng)報文:
JOB_CREATED響應(yīng)包類型為SUBMIT_JOB*的請求報文,數(shù)據(jù)部分為job handle
WORK_DATA, WORK_WARNING, WORK_STATUS, WORK_COMPLETE,WORK_FAIL, WORK_EXCEPTION
對于后臺運(yùn)行的工作任務(wù),任務(wù)執(zhí)行信息可以通過包類型為上面的值來查看。
STATUS_RES
響應(yīng)包類型為GET_STATUS的請求報文,通常用來查看一個后臺工作任務(wù)是否已經(jīng)完成,以及完成的百分比。
OPTION_RES
響應(yīng)包類型為OPTION_REQ的請求報文
worker發(fā)送的請求報文:
CAN_DO
通知job server可以執(zhí)行給定的function name的任務(wù),此worker將會放到一個鏈表,當(dāng)job server收到一個function name的工作任務(wù)時,worker為被喚醒。
CAN_DO_TIMEOUT
和CAN_DO類似,只是針對給定的function_name的任務(wù)設(shè)置了一個超時時間。
CANT_DO
worker通知job server已經(jīng)不能執(zhí)行給定的function name的任務(wù)
RESET_ABILITIES
worker通知job server不能執(zhí)行任何function name的任務(wù)
PRE_SLEEP
worker通知job server它將進(jìn)入sleep階段,而之后此worker會被包類型為NOOP的響應(yīng)報文喚醒。
GRAB_JOB
worker向job server抓取工作任務(wù),job server將會響應(yīng)NO_JOB或者JOB_ASSIG
NGRAB_JOB_UNIQ
和GRAB_JOB類似,但是job server在有工作任務(wù)時將會響應(yīng)JOB_ASSIGN_UNIQ
WORK_DATA
worker請求報文的數(shù)據(jù)部分更新client
WORK_WARNING
worker請求報文代表一個warning,它應(yīng)該被對待為一個WARNING
WORK_STATU
Sworker更新某個job handle的工作狀態(tài),job server應(yīng)該儲存這些信息,以便響應(yīng)之后client的GET_STATUS請求
WORK_COMPLETE
通知job server及所有連接的client,數(shù)據(jù)部分為返回給client的數(shù)據(jù)
WORK_FAIL
通知job server及所有連接的client,工作任務(wù)執(zhí)行失敗
WORK_EXCEPTION
通知job server及所有連接的client,工作任務(wù)執(zhí)行失敗并給出相應(yīng)的異常
SET_CLIENT_ID
設(shè)置worker ID,從而job server的控制臺及報告命令可以標(biāo)識各個worker,數(shù)據(jù)部分為worker實(shí)例的標(biāo)識
ALL_YOURS
暫未實(shí)現(xiàn)
worker獲取的響應(yīng)報文:
NOOP
job server喚醒sleep的worker,以便可以開始抓取工作任務(wù)
NO_JOB
job server響應(yīng)GRAB_JOB的請求,通知worker沒有等待執(zhí)行的工作任務(wù)
JOB_ASSIGN
job server響應(yīng)GRAB_JOB的請求,通知worker有需要執(zhí)行的工作任務(wù)
JOB_ASSIGN_UNIQ
job server響應(yīng)GRAB_JOB_UNIQ的請求,和JOB_ASSIGN一樣,只是為client傳遞了一個唯一標(biāo)識
基于上述的協(xié)議描述一個完整的例子
worker注冊可以執(zhí)行的工作任務(wù)
Worker -> Job Server
1 2 3 4 5 6 7 |
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檢測或者抓取工作任務(wù)
1 2 3 4 5 6 7 |
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響應(yīng)worker的抓取工作(沒有工作任務(wù))
1 2 3 4 5 |
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
1 2 3 4 5 |
00 52 45 51 0REQ (Magic) 00 00 00 04 4 (Packet type: PRE_SLEEP) 00 00 00 00 0 (Packet length) |
client提交工作任務(wù)
1 2 3 4 5 6 7 8 9 10 11 12 13 |
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 reverse0 (Function) 00 ? (Unique ID) 74 65 73 74 test (Workload) |
job server響應(yīng)client的SUBMIT_JOB請求,返回job handle
1 2 3 4 5 6 7 |
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
1 2 3 4 5 6 7 |
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的抓取工作任務(wù)
- 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分配工作任務(wù)給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完成工作任務(wù)通知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完成了工作任務(wù)
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可以完成多個工作任務(wù)的投遞,但是收到任務(wù)的執(zhí)行結(jié)果的順序可能與投遞的順序不一致。
6總結(jié)worker的工作流程
-
Worker通過CAN_DO消息,注冊到Job server上。
-
隨后發(fā)起GRAB_JOB,主動要求分派任務(wù)。
-
Job server如果沒有job可分配,就返回NO_JOB。
-
Worker收到NO_JOB后,進(jìn)入空閑狀態(tài),并給Job server返回PRE_SLEEP消息,告訴Job server:”如果有工作來的話,用NOOP請求我先?!?/p>
-
Job server收到worker的PRE_SLEEP消息后,明白了發(fā)送這條消息的worker已經(jīng)進(jìn)入了空閑態(tài)。
-
這時如果有job提交上來,Job server會給worker先發(fā)一個NOOP消息。
-
Worker收到NOOP消息后,發(fā)送GRAB_JOB向Job server請求任務(wù)。
-
Job server把工作派發(fā)給worker。
-
Worker干活,完事后返回WORK_COMPLETE給Job server。

浙公網(wǎng)安備 33010602011771號