定時任務Crontab

0、基本概念 & 實現原理python

 定時任務基本概念:linux

  • 調度器:負責管理Quartz應用運行時環境,用於調度定時任務。
  • 定時任務:按照某種時間規則,被調度的任務。

  a、從有無狀態來講,有如下兩種:數據庫

    有狀態任務:每次執行的任務是同一個實例,不能被並行執行;若是該任務的執行時間超過下次觸發的時刻,那麼下次的觸發將不會有做用。好比,一個有狀態任務執行時間是5分鐘,它的間隔時間是3分鐘;若是正在執行的時候,下次觸發時刻到達,則不會被執行。api

    無狀態任務:每次執行任務都是一個新的實例,能夠並行執行。緩存

  b、從執行的任務類型來講,有如下三種:bash

    SCA服務任務:任務是一個SCA服務。服務器

    邏輯流任務:任務是一個邏輯流。併發

    任意方法任務:任務是一個方法。app

  c、觸發模式(觸發器):用於定義任務調度的時間規則,主要有下面兩種:負載均衡

    固定時刻觸發(簡單觸發器):通常用於實現間隔固定的時間執行任務,以及重複多少次,如每 2 小時執行一次,重複執行 5 次。

    日曆週期觸發(複雜觸發器):使用Unix 'cron-like'表達式來定義時間規則,即利用一個包含 7 個字段的表達式來表示時間調度方式。例如,"0 15 10 * * ? *" 表示天天的 10:15AM 執行任務。對於涉及到星期和月份的調度比較合適。

  d、錯失觸發:定時任務若是錯過觸發而沒有執行,好比系統中止;系統重啓後,就會針對錯失觸發的定時任務進行處理,通常有兩種錯失觸發策略(EOS_QRTZ_TRIGGERS表的MISFIRE_INSTR字段):

    當即從新觸發:默認策略,當即執行一次定時任務,而無論錯過幾回。MISFIRE_INSTR字段值爲1。

    錯過觸發:下次觸發時間到來,再觸發執行定時任務。MISFIRE_INSTR字段值爲2。

  定時任務配置界面以下:

             

 

定時任務的實現:

  • 單機模式:調度器啓動一個調度線程,根據觸發器進行輪詢,若是觸發時刻到達,分配一個執行線程,執行定時任務。其中調度器及其狀態、觸發器及其狀態、定時任務及其狀態信息都會持久化到數據庫中,因此係統中止,不會丟失定時任務;系統從新啓動,會從新定時觸發。
  • 集羣模式:定時任務的集羣,有負載均衡和故障切換的能力,能夠給調度器帶來高可用性和伸縮性。集羣管理的實現是,集羣上的每個節點經過共享同一個數據庫來工做的(Quartz經過啓動兩個維護線程來維護數據庫狀態實現集羣管理,一個是檢測節點狀態線程,一個是恢復任務線程),經過數據庫鎖來實現併發控制(若是不是集羣,使用內存鎖進行併發控制)。負載均衡是自動完成的,集羣的每一個節點會盡快觸發任務。當一個觸發器的觸發時間到達時,第一個節點將會得到任務,並改變任務狀態,成爲執行任務的節點。故障切換的發生是在當一個節點正在執行一個或者多個任務失敗的時候。當一個節點失敗了,其餘的節點會檢測到而且標識在失敗節點上正在進行的數據庫中的任務。任何被標記爲可恢復的任務都會被其餘的節點從新執行。沒有標記可恢復的任務只會被釋放出來,將會在下次相關觸發器觸發時執行。

  注:  若是是集羣模式,則要求每一個節點的時鐘必定要一致,不然將發生沒法預料的問題。建議簡單觸發器的間隔時間不要小於20秒。

 

Cron 是一個linux下的定時執行工具,也是Linux的內置服務,能夠在不用人工干預的狀況下運行做業

/sbin/service crond start   # 啓動服務

/sbin/service crond stop   # 關閉服務

/sbin/service crond restart     # 重啓服務

/sbin/service crond reload  # 從新載入配置 

/etc/rc.d/rc.local 這個腳本的末尾加上:  /sbin/service crond start    那麼Cron這個服務就已經在進程裏面了,咱們就能夠用這個服務了。

 

 

Cron提供的接口:

使用crontab命令編輯, cron服務提供crontab命令來設定cron服務的,參數說明:
  crontab -u   # 設定某個用戶的cron服務,通常root用戶在執行這個命令的時候須要此參數

  crontab -l   # 列出某個用戶cron服務的詳細內容

  crontab -r   # 刪除每一個用戶的cron服務

  crontab -e   # 編輯某個用戶的cron服務   

  root查看本身的cron設置:  crontab -u root -l

  root刪除fredcron設置:  crontab -u fred -r

  編輯cron服務的格式和約定: crontab -u root -e

  進入vi編輯模式:      */1 * * * * ls >> /tmp/ls.txt

 

crontab命令選項:
  -u  指定一個用戶,

  -l  列出某個用戶的任務計劃,

  -r  刪除某個用戶的任務,

  -e  編輯某個用戶的任務

 

任務調度的crond常駐命令:crond linux用來按期執行程序的命令。操做系統安裝完成以後,默認會啓動此任務的調度命令crond命令每分鍾會按期檢查是否有要執行的工做,若是有要執行的工做便會自動執行該工做。

Linux任務調度的工做主要分爲如下兩類:

  • 系統執行的工做:系統週期性所要執行的工做,如備份系統數據、清理緩存
  • 我的執行的工做:某個用戶按期要作的工做,例如每隔10分鐘檢查郵件服務器是否有新信,這些工做可由每一個用戶自行設置。

cron服務每分鐘不只要讀一次 /var/spool/cron 內的全部文件,還須要讀一次 /etc/crontab ,所以咱們配置這個文件也能運用cron服務作一些事情。用crontab配置是針對某個用戶的,而編輯 /etc/crontab 是針對系統的任務。

 

原理解析

Cron服務是由 守護進程crond和一組crontab文件 組成crond守護進程是在系統啓動時由init進程啓動的,受init進程的監視,若是它不存在了,會被init進程從新啓動。這個守護進程每分鐘喚醒一次,並經過檢查crontab文件(任務表)判斷須要執行什麼任務每一個用戶有一個以用戶名命名的crontab文件,存放在 /var/spool/cron/crontabs 目錄裏。若管理員容許或者禁止其餘用戶擁有crontab文件,則應編輯 /etc/cron.deny etc/cron.allow 這兩個文件來禁止或容許用戶擁有本身的 crontab文件(每個用戶均可以有本身的crontab文件,但在一個較大的系統中,系統管理員通常會禁止這些文件,而只在整個系統保留一個這樣的文件)

crontab其實是啓動服務後讀取全部配置文件,而後睡眠一分鐘以後運行下一個任務,crontab服務啓動後,會檢查 /var/spool/cron/tabs 下全部用戶的定時任務,而後加載到內存的隊列中,而後每分鐘檢查一下 crontab文件是否有改動。能夠理解爲cron服務有2個線程,一個是調度處理定時任務,一個後臺線程,後臺線程檢查配置文件是否有變更,若是有變更,則發送信號到調度進程,調度進程再從新讀取配置文件更新內存中的任務隊列,同理,service cron stop 也是發信號到cron服務(本次確認cron服務半僵死就是由於沒法響應了)致使調度線程不知道變更,沒有更新內存中的隊列。從 /var/log/messages 觀察,依然是修改或刪除以前的定時任務在運行。 所以,爲了保險,在用戶裏 crontab -r 刪除用戶的定時任務後,建議重啓一下crontab服務(service cron stop後記得service cron status 查看一下是否中止成功,若是沒有 kill -9 再 service cron start),也就是清空一下當前定時任務的內存隊列,讓cron服務從新加載,更重要的是防止cron服務掛住沒從新加載定時任務隊列。

 

 

3.cron文件語法:

分 小時 日 月 星期 命令

0-59 0-23 1-31 1-12 0-6 command (取值範圍,0表示週日通常一行對應一個任務)


4.記住幾個特殊符號的含義:

"*"  表明取值範圍內的數字,

"/"  表明"每",

"-"  表明從某個數字到某個數字,

","  分開幾個離散的數字 1、任務調度設置文件的寫法 可用crontab -e命令來編輯,編輯的是/var/spool/cron下對應用戶的cron文件,也能夠直接修改/etc/crontab文件 具體格式以下:

Minute Hour Day Month Dayofweek command

分鐘 小時 天 月 天每星期 命令 每一個字段表明的含義以下:

Minute 每一個小時的第幾分鐘執行該任務

Hour 天天的第幾個小時執行該任務

Day 每個月的第幾天執行該任務

Month 每一年的第幾個月執行該任務

DayOfWeek 每週的第幾天執行該任務

Command 指定要執行的程序 在這些字段裏,除了「Command」是每次都必須指定的字段之外,其它字段皆爲可選字段,可視須要決定。對於不指定的字段,要用「*」來填補其位置。 舉例以下:

5 * * * * ls 指定每小時的第5分鐘執行一次ls命令

30 5 * * * ls 指定天天的 5:30 執行ls命令

30 7 8 * * ls 指定每個月8號的7:30分執行ls命令

30 5 8 6 * ls 指定每一年的6月8日5:30執行ls命令

30 6 * * 0 ls 指定每星期日的6:30執行ls命令[注:0表示星期天,1表示星期1,以此類推,也能夠用英文來表示,sun表示星期天,mon表示星期一等。]

30 3 10,20 * * ls 每個月10號及20號的3:30執行ls命令[注:「,」用來鏈接多個不連續的時段]

25 8-11 * * * ls 天天8-11點的第25分鐘執行ls命令[注:「-」用來鏈接連續的時段]

*/15 * * * * ls 每15分鐘執行一次ls命令 [即每一個小時的第0 15 30 45 60分鐘執行ls命令 ]

30 6 */10 * * ls 每月中,每隔10天6:30執行一次ls命令[即每個月的一、十一、2一、31日是的6:30執行一次ls命令。 ]

天天7:50以root 身份執行/etc/cron.daily目錄中的全部可執行文件

50 7 * * * root run-parts /etc/cron.daily [ 注:run-parts參數表示,執行後面目錄中的全部可執行文件。 ]



2、新增調度任務 新增調度任務可用兩種方法:

一、在命令行輸入: crontab -e 而後添加相應的任務,wq存盤退出。

二、直接編輯/etc/crontab 文件,即vi /etc/crontab,添加相應的任務。 3、查看調度任務



crontab -l //列出當前的全部調度任務

crontab -l -u jp //列出用戶jp的全部調度任務 4、刪除任務調度工做



crontab -r //刪除全部任務調度工做 5、任務調度執行結果的轉向 例1:天天5:30執行ls命令,並把結果輸出到/jp/test文件中

30 5 * * * ls >/jp/test 2>&1

注:2>&1 表示執行結果及錯誤信息。 編輯/etc/crontab 文件配置cron

 

 

系統任務格式:

SHELL=/bin/bash

PATH=/sbin:/bin:/usr/sbin:/usr/bin



MAILTO=root //若是出現錯誤,或者有數據輸出,數據做爲郵件發給這個賬號 HOME=/ //使用者運行的路徑,這裏是根目錄

# run-parts

01 * * * * root run-parts /etc/cron.hourly

//每小時執行/etc/cron.hourly內的腳本

02 4 * * * root run-parts /etc/cron.daily

//天天執行/etc/cron.daily內的腳本

22 4 * * 0 root run-parts /etc/cron.weekly

//每星期執行/etc/cron.weekly內的腳本

42 4 1 * * root run-parts /etc/cron.monthly

//每個月去執行/etc/cron.monthly內的腳本   

你們注意"run-parts"這個參數了,若是去掉這個參數的話,後面就能夠寫要運行的某個腳本名,而不是文件夾名了

例如:

一、在命令行輸入: crontab -e 而後添加相應的任務,wq存盤退出。

二、直接編輯/etc/crontab 文件,即vi /etc/crontab,添加相應的任務

11 2 21 10 * rm -rf /mnt/fb

 

1、相關配置

  • /var/spool/cron/   用於存放每一個用戶包括root的crontab任務,每一個任務以建立者的名字命名
  • /etc/crontab   此文件負責調度各類管理和維護任務。
  • /etc/cron.d/      用於存聽任何要執行的crontab文件或腳本。
  • /etc/cron.hourly、/etc/cron.daily、/etc/cron.weekly、/etc/cron.monthly     用於存放腳本,可以讓它每小時/天/星期、月執行一次。

 

2、經常使用命令:

crontab [-u username]    // 省略用戶表表示操做當前用戶的crontab -e (編輯工做表) -l (列出工做表裏的命令) -r (刪除工做)

crontab -e 進入當前用戶的工做表編輯,crontab的命令構成爲‘時間+動做’,其時間有分、時、日、月、周五種,操做符有:
  • * 取值範圍內的全部數字
  • / 每過多少個數字
  • - 從X到Z
  • 散列數字

 

3、crontab時間說明

# .---------------- minute (0 - 59) 
# |  .------------- hour (0 - 23)
# |  |  .---------- day of month (1 - 31)
# |  |  |  .------- month (1 - 12) OR jan,feb,mar,apr ... 
# |  |  |  |  .---- day of week (0 - 6) (Sunday=0 or 7)  OR
# |  |  |  |  |
# |  |  |  |  |
# *  *  *  *  *  command to be executed

minute:表明一小時內的第幾分,範圍 0-59。
hour:表明一天中的第幾小時,範圍 0-23。
mday:表明一個月中的第幾天,範圍 1-31。
month:表明一年中第幾個月,範圍 1-12。
wday:表明星期幾,範圍 0-7 (0及7都是星期天)。
who:要使用什麼身份執行該指令,當您使用 crontab -e 時,沒必要加此字段。
command:所要執行的指令。
 

4、crontab服務狀態

sudo service crond start     # 啓動服務
sudo service crond stop      # 關閉服務
sudo service crond restart   # 重啓服務
sudo service crond reload    # 從新載入配置
sudo service crond status    # 查看服務狀態

 

5、crontab命令

crontab $filepath    # 從新指定crontab定時任務列表文件

crontab -l              # 查看crontab定時任務
    
crontab -e             # 編輯定時任務【刪除-添加-修改】

# 添加定時任務
Step-One : 編輯任務腳本【分目錄存放】【ex: backup.sh】
Step-Two : 編輯定時文件【命名規則:backup.cron】
Step-Three : crontab命令添加到系統crontab backup.cron
Step-Four : 查看crontab列表 crontab -l

 

 

6、實例

# 實例1:每1分鐘執行一次myCommand
* * * * * myCommand

# 實例2:每小時的第3和第15分鐘執行
3,15 * * * * myCommand

# 實例3:在上午8點到11點的第3和第15分鐘執行
3,15 8-11 * * * myCommand

# 實例4:每隔兩天的上午8點到11點的第3和第15分鐘執行
3,15 8-11 */2  *  * myCommand

# 實例5:每週一上午8點到11點的第3和第15分鐘執行
3,15 8-11 * * 1 myCommand

# 實例6:每晚的21:30重啓smb
30 21 * * * /etc/init.d/smb restart

# 實例7:每個月一、十、22日的4 : 45重啓smb
45 4 1,10,22 * * /etc/init.d/smb restart

# 實例8:每週6、週日的1 : 10重啓smb
10 1 * * 6,0 /etc/init.d/smb restart

# 實例9:天天18 : 00至23 : 00之間每隔30分鐘重啓smb
0,30 18-23 * * * /etc/init.d/smb restart

# 實例10:每星期六的晚上11 : 00 pm重啓smb
0 23 * * 6 /etc/init.d/smb restart

# 實例11:每一小時重啓smb
* */1 * * * /etc/init.d/smb restart

# 實例12:晚上11點到早上7點之間,每隔一小時重啓smb
* 23-7/1 * * * /etc/init.d/smb restart


# 天天早上6點 
0 6 * * * echo "Good morning." >> /tmp/test.txt //注意單純echo,從屏幕上看不到任何輸出,由於cron把任何輸出都email到root的信箱了。

# 每兩個小時 
0 */2 * * * echo "Have a break now." >> /tmp/test.txt  

# 晚上11點到早上8點之間每兩個小時和早上八點 
0 23-7/2,8 * * * echo "Have a good dream" >> /tmp/test.txt

# 每月的4號和每一個禮拜的禮拜一到禮拜三的早上11點 
0 11 4 * 1-3 command line

# 1月1日早上4點 
0 4 1 1 * command line SHELL=/bin/bash PATH=/sbin:/bin:/usr/sbin:/usr/bin MAILTO=root //若是出現錯誤,或者有數據輸出,數據做爲郵件發給這個賬號 HOME=/ 

# 每小時(第一分鐘)執行/etc/cron.hourly內的腳本
01 * * * * root run-parts /etc/cron.hourly

# 天天(凌晨4:02)執行/etc/cron.daily內的腳本
02 4 * * * root run-parts /etc/cron.daily 

# 每星期(週日凌晨4:22)執行/etc/cron.weekly內的腳本
22 4 * * 0 root run-parts /etc/cron.weekly 

# 每個月(1號凌晨4:42)去執行/etc/cron.monthly內的腳本 
42 4 1 * * root run-parts /etc/cron.monthly 

# 注意:  "run-parts"這個參數了,若是去掉這個參數的話,後面就能夠寫要運行的某個腳本名,而不是文件夾名。   

# 天天的下午4點、5點、6點的5 min、15 min、25 min、35 min、45 min、55 min時執行命令。 
5,15,25,35,45,55 16,17,18 * * * command

# 每週一,三,五的下午3:00系統進入維護狀態,從新啓動系統。
00 15 * *1,3,5 shutdown -r +5

# 每小時的10分,40分執行用戶目錄下的innd/bbslin這個指令: 
10,40 * * * * innd/bbslink 

# 每小時的1分執行用戶目錄下的bin/account這個指令: 
1 * * * * bin/account

# 天天早晨三點二十分執行用戶目錄下以下所示的兩個指令(每一個指令以;分隔): 
203 * * * (/bin/rm -f expire.ls logins.bad;bin/expire$#@62;expire.1st) 

 

7、Django中的定時任務

# 添加定時任務到系統中
python manage.py crontab add

# 顯示已經激活的定時任務
python manage.py crontab show

# 移除定時任務
python manage.py crontab remove
相關文章
相關標籤/搜索