替代crontab,任務計劃統一集中管理系統cronsun簡介
一、背景
crontab 是 Linux 系統裡面最簡單易用的定時任務管理工具,相信絕大多數開發和運維都用到過。在咱們公司,很多業務系統的定時任務都是通過 crontab 來定義的,時間長了後會發現存在很多問題:
- 大量的 crontab 任務散佈在各臺伺服器,帶來了很高的維護成本
- 任務沒有按時執行,甚至失敗了很久才發現,需要重試或排查
- crontab 分散在很多叢集上,需要一臺一臺去看日誌分析,頭都大了
- crontab 存在單點問題,對於不能重複執行的定時任務很傷腦筋
- 我 X,crontab 被誤刪了,沒備份?尼瑪!
- 我 Q,伺服器要遷移,crontab 上的歷史任務都是什麼鬼?問了一圈居然都不知道
- …
因此,我們非常需要一個集中管理定時任務系統,相信這也是的飽受 crontab 煎熬的運維或開發的心聲。
二、選擇
一個開源專案:cronsun,也就是本文介紹的主角,通過試用,發現非常契合我們當前的使用場景,介紹如下:
cronsun 是一個分散式任務系統,單個節點和 Linux 機器上的 crontab 近似。是為了解決多臺 Linux 機器上 crontab 任務管理不方便的問題,同時提供任務高可用的支援(當某個節點宕機的時候可以自動排程到正常的節點執行)。支援介面管理機器上的任務,支援任務失敗郵件提醒,安裝簡單,使用方便,是替換 crontab 一個不錯的選擇。
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
②、解壓後修改 conf 目錄下的配置檔案:db.json 和 etcd.json,分別修改 MongoDB 和 etcd 的實際地址。
③、啟動 web:./cronweb -conf conf/base.json (若要後臺執行則使用 nohup)
④、啟動 node:./cronnode -conf conf/base.json (若要後臺執行則使用 nohup)
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、更新記錄
重要功能更新:
①、已支援指令碼引數;
②、已支援歷史日誌定期清理;
③、3.1 版本開始使用 UUID 作為節點唯一標識。