go-forest分布式任務調(diào)度平臺
前言
在企業(yè)系統(tǒng)開發(fā)過程中難免少不了一些定時任務來進行定時觸發(fā)執(zhí)行任務,對于非分布式環(huán)境系統(tǒng)中,我們只需要在對應系統(tǒng)中內(nèi)部集成一些調(diào)度庫進行配置定時觸發(fā)即可。
比如:使用 Spring 框架集成 quartz ,只需要進行一些簡單的配置就能定時執(zhí)行任務了。但是隨著企業(yè)的系統(tǒng)越來越多、逐步從單一應用慢慢演變?yōu)槲⒎占骸?br> 在分布式集群系統(tǒng)中主要面臨出如:任務的重復執(zhí)行、沒有統(tǒng)一定時任務配置、任務節(jié)點故障轉(zhuǎn)移、任務監(jiān)控&報警等一些列的功能都是要在分布式系統(tǒng)中進行解決。
此分布式的定時任務調(diào)度平臺,它非常輕量小巧,使用簡單,后端以中心服務器為調(diào)度核心,負責集群中各種任務的動態(tài)分配和調(diào)度執(zhí)行。
在平臺前端支持 Web 界面可視化管理,我們可以創(chuàng)建、暫停/啟動任務、刪除未執(zhí)行的任務快照、或者查看任務的調(diào)度狀態(tài)和執(zhí)行日志。
任務抽象調(diào)度任務中心不負責業(yè)務任務格式,只負責將任務快照分發(fā)到指定的客戶端即可。
系統(tǒng)架構
可以部署 N 個 Node 節(jié)點,同一時刻只有一臺 Leader 節(jié)點,只有選舉成功的Leader節(jié)點才有派發(fā)任務的權限。任務客戶端啟動時候通過 Etcd 進行注冊客戶端元數(shù)據(jù)信息。
角色
Job Node Leader
任務調(diào)度集群負責任務的配置管理、監(jiān)控、任務統(tǒng)計、故障轉(zhuǎn)移以及任務分發(fā)工作。整個任務調(diào)度集群只有一臺 Job Node 是 Leader。
Job Node Follower
任務調(diào)度集群負責任務的配置管理以及監(jiān)控,整個任務調(diào)度集群可以有 N 臺 Job Node 是 Follower。沒有故障轉(zhuǎn)移、任務分發(fā)能力,當Job Node Leader 不可用下線后觸發(fā)選舉,才有機會成為Leader節(jié)點。
任務集群(Group)
為了發(fā)揮集群的處理業(yè)務作業(yè)的能力,我們不可能只希望作業(yè)集群中的某一臺只執(zhí)行作業(yè)。任務集群是將同一個任務或者同一組的任務并發(fā)分散到不同的作業(yè)機器中。發(fā)揮更大的作業(yè)能力。
任務作業(yè)(Client)
任務作業(yè)(Client)是每一臺作業(yè)機器重啟后會自動注冊至Etcd中方便Job Node Leader 能夠?qū)⒅付ǖ娜蝿辗峙浣o自己。自己作業(yè)完畢會將結果回傳給Etcd指定的目錄中以方便Leader進行統(tǒng)計收集工作。
選舉
由于一個任務調(diào)度集群有多臺提供服務,我們在可以從集群節(jié)點中選舉出一臺領導節(jié)點來進行發(fā)號師令,比較成熟的選舉算法(Paxos、Raft 等)這里不做討論。這里使用etcd中的租約機制來實現(xiàn)選舉功能。
當一個調(diào)度服務節(jié)點啟動的時候首先嘗試發(fā)起選舉請求(PUT 節(jié)點 /forest/server/elect/leader),如果執(zhí)行成功則選舉成功。如果判斷已經(jīng)有其他調(diào)度服務節(jié)點已經(jīng)選舉成功過則放棄選舉請求并進行監(jiān)聽(/forest/server/elect/leader)選舉節(jié)點變化。如果有領導下線通知則立即發(fā)起選舉。
在任務調(diào)度服務集群中一條任務配置在同一時刻保證只能觸發(fā)一次任務,如果所有的任務集群都觸發(fā)了次任務那就說明此任務被重復的執(zhí)行了N次。我們需要從調(diào)度集群中選舉出一個調(diào)度Leader節(jié)點進行指揮。
只有Leader調(diào)度節(jié)點才能分發(fā)任務,其他的Follower節(jié)點沒有權限分發(fā)任務,一旦Leader調(diào)度Node掛掉,其他Follower節(jié)點則會重新選舉,誕生一臺新的Leader節(jié)點繼續(xù)指揮服務。
平臺特點
1. 通過[Web界面管理](https://github.com/busgo/duck),操作簡單方便,支持各種任務
2. 高可用可以部署N臺調(diào)度集群節(jié)點,保證沒有單點故障。
3. 部署簡單、僅僅需要一個執(zhí)行文件即可運行。
4. 集成方便,統(tǒng)一任務抽象,接入sdk so easy!
5. 任務故障轉(zhuǎn)移,任務客戶端下線自動切至在線客戶端任務機器。
快速開始
sql腳本
CREATE TABLE `job_execute_snapshot` (
`id` VARCHAR (64) NOT NULL COMMENT '主鍵',
`job_id` VARCHAR (32) NOT NULL COMMENT '任務定義id',
`name` VARCHAR (32) NOT NULL COMMENT '任務名稱',
`group` VARCHAR (32) NOT NULL COMMENT '任務集群',
`cron` VARCHAR (32) NOT NULL COMMENT 'cron表達式',
`target` VARCHAR (255) NOT NULL COMMENT '目標任務',
`params` VARCHAR (255) DEFAULT NULL COMMENT '參數(shù)',
`ip` VARCHAR (32) NOT NULL COMMENT 'ip',
`status` TINYINT (4) NOT NULL COMMENT '狀態(tài) 1-執(zhí)行中 2-完成 3-未知 4-錯誤',
`mobile` VARCHAR (32) DEFAULT NULL COMMENT '手機號碼',
`remark` VARCHAR (255) DEFAULT NULL COMMENT '備注',
`create_time` VARCHAR (32) NOT NULL COMMENT '創(chuàng)建時間',
`start_time` VARCHAR (255) DEFAULT NULL COMMENT '開始時間',
`finish_time` VARCHAR (32) DEFAULT NULL COMMENT '結束時間',
`times` BIGINT (20) DEFAULT '0' COMMENT '耗時',
`result` VARCHAR (255) DEFAULT NULL COMMENT '返回結果',
PRIMARY KEY (`id`),
KEY `ip` (`ip`),
KEY `job_id` (`job_id`),
KEY `status` (`status`),
KEY `group` (`group`)
) ENGINE = INNODB DEFAULT CHARSET = utf8 COMMENT = '任務作業(yè)執(zhí)行快照';
先決條件
golang(>=1.11)
git
源代碼安裝
git clone https://github.com/busgo/forest.git
cd forest/forest
go build forest.go
等待自動下載依賴庫
appledeMacBook-Pro:forest apple$ go build forest.go
go: finding github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2
go: finding github.com/dgrijalva/jwt-go v3.2.0+incompatible
go: finding github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6
go: finding github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f
go: finding github.com/coreos/go-systemd v0.0.0-20190620071333-e64a0ec8b42a
go: finding github.com/prometheus/client_golang v1.0.0
go: finding github.com/coreos/bbolt v1.3.3
go: finding github.com/prometheus/common v0.4.1
go: finding github.com/grpc-ecosystem/go-grpc-middleware v1.0.0
go: finding github.com/coreos/etcd v3.3.13+incompatible
go: finding github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5
go: finding github.com/grpc-ecosystem/grpc-gateway v1.9.4
go: finding github.com/gogo/protobuf v1.1.1
go: finding github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc
go: finding github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d
go: finding gopkg.in/yaml.v2 v2.2.1
...
如果下載依賴庫出現(xiàn)超時問題,請重復執(zhí)行編譯命令直到成功為止。
查詢命令參數(shù)
appledeMacBook-Pro:forest apple$ ./forest -help
flag needs an argument: -help
Usage of ./forest:
-db-url string
db url for mysql (default "root:123456@tcp(127.0.0.1:3306)/forest?charset=utf8")
-etcd-dailtimeout int
etcd dailtimeout (default 5)
-etcd-endpoints string
etcd endpoints (default "127.0.0.1:2379")
-help string
forest help
-http-address string
http address (default ":2856")
啟動服務
nohup etcd > etcd.log 2>&1 &
nohup forest > forest.log 2>&1 &
appledeMacBook-Pro:forest apple$ tail -500f forest.log
{"time":"2019-07-25T15:05:40.041263+08:00","level":"-","prefix":"-","file":"node.go","line":"71","message":"the job node:192.168.10.35, success register to :/forest/server/node/192.168.10.35"}
____ __
/ __/___/ / ___
/ _// __/ _ \/ _ \
/___/\__/_//_/\___/ v3.3.10-dev
High performance, minimalist Go web framework
https://echo.labstack.com
____________________________________O/_______
O\
{"time":"2019-07-25T15:05:40.046041+08:00","level":"INFO","prefix":"-","file":"group.go","line":"92","message":"add a new group:account,for path:/forest/server/group/account"}
{"time":"2019-07-25T15:05:40.046172+08:00","level":"INFO","prefix":"-","file":"group.go","line":"92","message":"add a new group:order,for path:/forest/server/group/order"}
{"time":"2019-07-25T15:05:40.049989+08:00","level":"-","prefix":"-","file":"node.go","line":"210","message":"the job node:192.168.10.35,elect success to :/forest/server/elect/leader"}
{"time":"2019-07-25T15:05:40.050021+08:00","level":"INFO","prefix":"-","file":"group.go","line":"92","message":"add a new group:trade,for path:/forest/server/group/trade"}
? http server started on [::]:2856
交叉編譯
# mac os
GOOS=darwin GOARCH=amd64 go build forest.go
# linux
GOOS=linux GOARCH=amd64 go build forest.go
# windows
GOOS=windows GOARCH=amd64 go build forest.go
安裝web分布式任務調(diào)度平臺
下載源碼[duck](https://github.com/busgo/duck)
git clone https://github.com/busgo/duck.git
cd duck
修改 request.js 文件中的地址
npm install
啟動服務
# 開發(fā)環(huán)境
npm run dev
# 生產(chǎn)環(huán)境
npm run-script build
Etcd 元數(shù)據(jù)目錄說明
### 選舉目錄
> /forest/server/elect/leader
是一個臨時節(jié)點,用于任務調(diào)度節(jié)點選舉,選舉成功將節(jié)點的ip寫入
### 調(diào)度節(jié)點注冊目錄
> /forest/server/node/%s
調(diào)度集群中的節(jié)點將自己的節(jié)點ip寫入
### 任務集群
> /forest/server/group/
任務集群信息全放入此目錄下
### 任務快照
> /forest/client/snapshot/%s/%s/%s
分配任務快照信息放入此目錄下
such as /forest/client/snapshot/trade/192.168.1.1/201901011111111323
### 任務客戶端信息
> /forest/client/%s/clients/
所有任務客戶端注冊此目錄下
such as /forest/client/trade/clients/192.168.1.1
### 任務作業(yè)上報目錄
> /forest/client/execute/snapshot/%s/%s/
such as /forest/client/execute/snapshot/trade/192.168.1.1/201901011111111323
管理任務
任務配置管理
新建任務
任務集群
任務執(zhí)行計劃
調(diào)度集群
任務快照
任務客戶端節(jié)點
任務作業(yè)快照
Client Libraries
jforest for java
gforest for go
待完善
1. ~~任務故障轉(zhuǎn)移~~
2. ~~任務執(zhí)行日志收集~~
3. 任務作業(yè)sdk
4. ~~手動執(zhí)行任務~~
5. ~~任務統(tǒng)計~~
6. 任務報警
7. ~~任務調(diào)度計劃同步~~
