定時任務在開發中是很是常見的一個需求,定時檢測過時優惠券、定時重啓、刷新緩存、備份數據等等均可以用到定時任務。在 Linux 上通常都是經過 crontab 來實現一個定時任務,這個是基於操做系統的;固然在應用層面也是能夠實現的,如使用 Swoole 的定時器,Laravel 框架的任務調度(本質上也是 crontab ), Quartz 分佈式任務調度框架等等。可是基於應用層面的定時任務侷限性比較大,通常都是隻能使用特定的語言來開發;好比 Swoole 通常都只能用 PHP 來開發;而經過 crontab 命令,咱們能夠在固定的時間間隔執行指定的系統指令或 shell 腳本,基本上就不限制於開發語言了。shell
在 Linux 下定義一個定時任務有兩種方式,一個是直接修改 /etc/crontab
文件,還有一個是經過 crontab -e
命令來編輯任務文件。這兩種方式的區別以下:apache
定義方式不一樣 直接修改 /etc/crontab
的話在定義的時候須要在 command 以前指定一個命令的執行用戶緩存
範圍不一樣 修改 /etc/crontab
只有 root 用戶能用,能夠更加方便的給其餘用戶設置計劃任務; crontab -e
這種全部用戶均可以使用,普通用戶也只能爲本身設置計劃任務,而後會自動寫入/var/spool/cron/usename
中bash
系統級任務與用戶級任務 系統級任務調度主要完成系統的一些維護操做,用戶級任務調度主要完成用戶自定義的一些任務,能夠將用戶級任務調度放到系統級任務調度來完成(不建議這麼作),可是反過來卻不行;root 用戶的任務調度操做能夠經過 crontab –uroot –e
來設置,也能夠將調度任務直接寫入 /etc/crontab
文件;須要注意的是,若是要定義一個定時重啓系統的任務,就必須將任務放到 /etc/crontab
文件,即便在 root 用戶下建立一個定時重啓系統的任務也是無效的。框架
crontab 的命令格式很簡單,這個是定義任務的,而不是定義任務文件(任務文件就是定義實際的什麼時間節點以及執行什麼任務)分佈式
crontab [-u user] file crontab [-u user] [ -e | -l | -r ]
複製代碼
簡單說一下參數的含義:ui
-u user:用來設定某個用戶的 crontab 服務
file: file 是命令文件的名字,指定一個文件而且該文件中寫好了各個定時任務, 而後 crontab 會讀取該文件內容而且載入 crontab
-e: 編輯某個用戶的 crontab 文件內容, 默認編輯當前用戶的 crontab 文件
-l: 顯示某個用戶的 crontab 文件內容,默認顯示當前用戶的 crontab 文件內容
-r: 從 /var/spool/cron 目錄中刪除某個用戶的 crontab 文件,默認刪除當前用戶的 crontab 文件
-i: 在刪除用戶的 crontab 文件時給確認提示
複製代碼
以上是使用 crontab 命令時的參數以及含義,這個文件格式纔是真正定義時間和任務的。格式以下:spa
* * * * * *
複製代碼
具體含義是:操作系統
第 1 列分鐘 0~59
第 2 列小時 0~23(0表示子夜)
第 3 列日 1~31
第 4 列月 1~12
第 5 列星期 0~7(0和7表示星期天)
第 6 列要運行的命令
複製代碼
能夠看一張圖片來加深記憶:rest
在使用的時候能夠直接經過 crontab -e
來打開而且編輯當前的定時任務配置文件, 而後能夠經過 crontab -l
來列出 crontab 文件內容.
* * * * * command
複製代碼
3,15 * * * * command
複製代碼
這個頗有用, 特別是在定時抓取一些開彩數據就能夠用到, 你懂的。
3,15 8-11 * * * command
複製代碼
3,15 8-11 * * 1 command
複製代碼
30 21 * * * /etc/init.d/smb restart
複製代碼
* */1 * * * /etc/init.d/smb restart
複製代碼
0 23-7 * * * /etc/init.d/smb restart
複製代碼
有時候建立了一個任務,可是這個任務卻沒法自動執行,而手動執行這個任務卻沒有問題,這種狀況通常是因爲在 crontab 文件中沒有配置環境變量引發的。 在 crontab 文件中定義多個調度任務時,須要特別注環境變量的設置,由於咱們手動執行某個任務時,是在當前 shell 環境下進行的,程序固然能找到環境變量,而系統自動執行任務調度時,是不會加載任何環境變量的,所以,就須要在 crontab 文件中指定任務運行所需的全部環境變量。建議在定義任務的時候路徑都使用絕對 路徑。
基本上 crontab 的最低檢測時間單位是分鐘,因此會每分鐘讀取一次 /etc/crontab
與 /var/spool/cron
中的數據內容;所以只要編輯完文件而且保存以後,crontab 時設定就會自動執行;固然若是重啓 crontab 則能夠當即執行了。當 crontab 失效時,能夠嘗試重啓:
/etc/init.d/crond restart
複製代碼
或者查看日誌看某個任務有沒有執行報錯:
tail -f /var/log/cron
複製代碼
附上 Ubuntu 上的重啓命令:
$sudo /etc/init.d/cron start
$sudo /etc/init.d/cron stop
$sudo /etc/init.d/cron restart
複製代碼
每條任務調度執行完畢,系統都會將任務輸出信息經過電子郵件的形式發送給當前系統用戶,這樣日積月累日誌信息會很是大,可能會影響系統的正常運行;所以,將每條任務進行重定向處理很是重要,能夠在定義任務的時候忽略日誌輸出:
0 */3 * * * /usr/local/apache2/apachectl restart >/dev/null 2>&1
複製代碼
歡迎關個人我的公衆號:左手代碼