一、背景
crontab 是 Linux 系統裏面最簡單易用的定時任務管理工具,相信絕大多數開發和運維都用到過。在咱們公司,很多業務系統的定時任務都是通過 crontab 來定義的,時間長了後會發現存在很多問題:
- 大量的 crontab 任務散佈在各臺服務器,帶來了很高的維護成本
- 任務沒有按時執行,甚至失敗了很久才發現,需要重試或排查
- crontab 分散在很多集羣上,需要一臺一臺去看日誌分析,頭都大了
- crontab 存在單點問題,對於不能重複執行的定時任務很傷腦筋
- 我 X,crontab 被誤刪了,沒備份?尼瑪!
- 我 Q,服務器要遷移,crontab 上的歷史任務都是什麼鬼?問了一圈居然都不知道
- …
因此,我們非常需要一個集中管理定時任務系統,相信這也是的飽受 crontab 煎熬的運維或開發的心聲。
二、選擇
一個開源項目:cronsun,也就是本文介紹的主角,通過試用,發現非常契合我們當前的使用場景,介紹如下:
cronsun 是一個分佈式任務系統,單個節點和 Linux 機器上的 crontab 近似。是爲了解決多臺 Linux 機器上 crontab 任務管理不方便的問題,同時提供任務高可用的支持(當某個節點死機的時候可以自動調度到正常的節點執行)。支持界面管理機器上的任務,支持任務失敗郵件提醒,安裝簡單,使用方便,是替換 crontab 一個不錯的選擇。
Github 地址:https://github.com/shunfei/cronsun
cronsun 的部署架構如下:
-
[web]
-
|
-
--------------------------
-
(add/del/update/exec jobs)| |(query job exec result)
-
[etcd] [mongodb]
-
| ^
-
-------------------- |
-
| | | |
-
[node.1] [node.2] [node.n] |
-
(job exec fail)| | | |
-
[send mail]<-----------------------------------------(job exec result)
三、部署
本文主要介紹功能,這裏就簡單寫下關鍵步驟(安裝部署使用都很好上手):
1、安裝 MongoDB,強烈建議使用集羣模式
2、安裝 Etcd3,強烈建議使用集羣模式
3、部署 cronsun
①、下載 cronsun:https://github.com/shunfei/cronsun/releases (選擇最新版本即可)
②、解壓後修改 conf 目錄下的配置文件:db.json 和 etcd.json,分別修改 MongoDB 和 etcd 的實際地址。
③、啓動 web:./cronweb -conf conf/base.json (若要後臺運行則使用 nohup)
④、啓動 node:./cronnode -conf conf/base.json (若要後臺運行則使用 nohup)
⑤、訪問前臺:http://x.x.x.x:7079/ui/
4、部署鑑權組件 aProxy,cronsun 在鑑權方面做的非常粗糙,所以這裏用到了 cronsun 團隊開發的 aProxy 鑑權組件,實現的原理爲基於 Go 語言,反向代理了後端 WEB,從而實現域名和頁面地址的訪問控制,介紹地址:https://www.cnblogs.com/QLeelulu/p/aproxy.html
我們這邊是要用到生產環境,所以在部署上會着重考慮到可用性和可靠性,這裏貼一下我們這邊的部署架構圖,供參考:
Ps:目前新版本已支持歷史日誌定期清理。
這裏,Etcd 和 MongoDB 複用了 5 臺服務器(後續會繼續複用其他公共組件),其中 MongoDB 採用分片+副本集的模式。
四、功能
部署完成後,訪問前臺就能看到 UI 比較簡陋 cronsun 管理 WEB 了:
Ps:右上方選擇熟悉的語言之後,基本就可以按照頁面標籤進行任務添加操作了。
1、添加節點
cronsun 基於 etcd 實現了自動發現和註冊的功能,所以添加節點非常簡單,直接將 cronnode 和 conf 拷貝到客戶端服務器啓動之後,就能在前臺->節點頁面看到該服務器了,當然節點和 Etcd 以及 MongoDB 之間的網絡必須暢通。
2、節點分組
添加了所需的節點服務器之後,我們可以將節點進行分組,從而方便定時任務的添加:
3、添加任務
節點和分組都搞定之後,我們就可以開始添加定時任務了。定時任務填寫的信息略微複雜,不過按照提示還是可以輕鬆搞定的:
上圖我簡單的標註了一些需要特別說明的地方,其他的選項大家看中文描述都能自行搞定。當然,還有一點要說明的是,任務腳本必須要有執行權限,否則任務會執行失敗。
4、任務列表
添加完成任務之後,在任務標籤頁就能看到所有添加的定時任務以及執行情況了,這裏可以使用分組過濾或節點過濾來篩選關心的任務。
每一個任務的右側有 3 個小按鈕:
①、成功/失敗:顯示最近一個任務的執行是成功還是失敗,點擊後可以查看到任務詳情,包括任務輸出數據:
②、latest 按鈕:點擊後查看改任務的近期執行情況
③、刷新符號按鈕:點擊後可以彈出立即執行功能,方便調試任務
五、小結
通過一段時間的灰度試用,可以確定 cronsun 在中小型規模場景下,是 crontab 的一個比較好的替代品,它能夠幫助運維人員脫離 crontab 難管理、難運維的苦海。
當然,作爲一款開源產品,cronsun 很多功能細節還有很大的提升空間,目前我也和 cronsun 團隊長期保持聯繫,將生產環境使用過程中遇到的一些問題和建議一一反饋,相信這款產品能夠繼續打磨優化,更加完善、完美。
六、問題及更新【持續】
問題記錄:
1、告警配置
首先要清楚 cronsun 的告警是由 cronweb 發出的,而不是 cronnode(但是 cronnode 的 mail.json 也必須 Enable:true,否則還是無法發出告警)。
其次,編輯 cronweb 和 cronnode 的配置文件:mail.json,如下內容
-
{
-
"Enable": true,
-
"To": ["這裏填寫缺省默認的告警郵件接收地址"],
-
"#HttpAPI": "如有此字段,則按 http api 方式發送",
-
"#Keepalive": "如果此時間段內沒有郵件發送,則關閉 SMTP 連接,單位/秒",
-
"Keepalive": 30,
-
"#doc": "https://godoc.org/github.com/go-gomail/gomail#Dialer",
-
"Host": "填寫SMTP服務器地址,比如:stmp.qq.com",
-
"Port": 25,
-
"Username": "這裏填寫發送人郵箱地址(用於登陸SMTP+from地址)",
-
"Password": "登陸密碼",
-
"SSL": false,
-
"LocalName": ""
-
}
Ps:LocalName 建議留空,HttpAPI 模式未使用到,這裏省略之,請自行測試。
最後啓動 cronweb 即可實現郵件告警。
當然, 還需要在 web 上的單向任務界面開啓告警才行,如下圖所示:
Ps:cronweb 的 mail.json 配置中必須將 Enable 填爲 true 纔可以看到上圖的告警開關按鈕,否則不顯示。
2、更新記錄
詳見 github 版本發佈頁面:https://github.com/shunfei/cronsun/releases
重要功能更新:
①、已支持腳本參數;
②、已支持歷史日誌定期清理;
③、3.1 版本開始使用 UUID 作爲節點唯一標識。