第十三節 定時任務補充
標籤(空格分隔): Linux實戰教學筆記java
---[更多資料點我查看][1]node
1,生產環境經常使用Crontab專業實例
1.1書寫crontab定時任務多個基本要領
1.1.1 規範定時任務兩例
例1:每分鐘打印一次本身的名字拼音全拼到「/server/log/本身的名字命名的文件」中。linux
[root@chensiqi1 ~]# mkdir -p /server/log/ [root@chensiqi1 ~]# echo "chensiqi" >>/server/log/chensiqi [root@chensiqi1 ~]# cat /server/log/chensiqi chensiqi [root@chensiqi1 ~]# crontab -e crontab: installing new crontab [root@chensiqi1 ~]# crontab -l ##print name to file * * * * * /bin/echo "chensiqi" >>/server/log/chensiqi [root@chensiqi1 ~]#
解答:
方法1:web
#print my name to log by chensiqi at 2017211 * * * * * /bin/echo "chensiqi" >>/server/log/chensiqi
方法2shell
#print my name to log by chensiqi at 2017211 */1 * * * * /bin/echo "chensiqi" >>/server/log/chensiqi >dev/null 2>&1 提示:這是一個錯誤的定時任務,請同窗們思考錯在了哪裏?
解答知識小結:數據庫
1,定時任務要加註釋
2,若是已經要定向到文件中,結尾不要有>/dev/null 2>&1
3,/server/log目錄必需要存在才能出結果,如沒有建立這個目錄。
4,定時任務中的路徑必定要絕對路徑
5,crond服務必須首先開啓
6,查看定時任務日誌tail /var/log/croncentos
例2:每週六,日上午9點和下午14點(執行/server/scripts/chensiqi.sh).要求:/server/scripts/chensiqi.sh腳本的功能是打印當天的日期:格式爲2017-02-11能夠隨意。ruby
解答:bash
## 00 9,14 * * 0,6 /bin/sh /server/scripts/chensiqi.sh >/dev/null 2>&1
步驟:markdown
- 1,建立對應的目錄
mkdir /server/scripts -p
- 2,命令行測試
date +%F 2017-02-11
- 3,書寫腳本
echo 'date +%F' >/server/scripts/chensiqi.sh cat /server/scripts/chensiqi.sh
- 4,命令行測試腳本
/bin/sh /server/scripts/chensiqi.sh
2017-02-11 - 5,編輯定時任務(讓他快速執行*****)
crontab -e#sync time chensiqi at 20170211 */5 * * * * /usr/sbin/ntpdate ntp1.aliyun.com >>/server/log/chensiqi.log 2>&1
注意:
測試的時候最好定向到一個文件中。
- 6,測試
tail -f /server/log/chensiqi.log
2017-02-11 - 7,按照原來的要求更改定時任務的時間
#go to chensiqi trainning by chensiqi at 20170211 00 09,14 * * 0,6 /bin/sh /server/scripts/chensiqi.sh >>/server/log/chensiqi.log
技巧:
- 定時任務必定要儘可能用腳本實現。
- 命令行操做成功,而後放入腳本執行(/bin/sh 腳本全路徑)成功,最後在配置任務
- 複製操做成功的命令行腳本,再定時任務裏黏貼配置。
- 加/bin/sh執行腳本 /bin/sh /server/script/chensiqi.sh
- 要把腳本的執行結果定向到空或者是一個文件中,不要什麼都不加。
1.1.2 定時任務書寫要領
- 要領1:爲定時任務規則加必要的註釋
加必要註釋:寫定時任務規則時儘量的加上註釋(最好是英文註釋),這是個好的習慣和規範。
例如:誰在什麼時間幹了什麼(註釋內容)什麼人,什麼時間,由於什麼,作了什麼。若是這些都標記清楚了,這樣其餘的運維人員能夠很容易的理解任務的信息,從而提高團隊的工做效率。
- 要領2:執行shell腳本任務前加/bin/sh
執行定時任務時,若是是執行腳本,請儘可能在腳本前面加上/bin/sh命令,不然有可能由於忘了爲腳本設定執行權限(x),從而覺得OK了,結果沒法完成任務,這樣就「悲劇」了
- 要領3:定時任務命令或腳本的結尾加>/dev/null 2>&1
定時任務(通常是腳本任務)規則的結尾最好加上>/dev/null 2>&1等內容,若是須要打印日誌,則能夠追加到指定的日誌文件裏(此時不要和/dev/null同時存在),儘可能不要留空。若是任務是命令的話,結尾使用「>/dev/null 2>&1」時要多測試下,要有檢查手段。如:/1 * * * echo "==" >>/tmp/chensiqi.log>/dev/null 2>&1 任務規則就是沒法執行的。
- 要領4:定時任務命令超過2條的命令執行,最好用腳本文件
超過2條的命令執行,最好用腳本文件。下面的方法就是不規範的,不專業的。* * * * * sleep 1;echo chensiqi >> /server/log/chensiqi.log
標準寫法:
[root@chensiqi /]# cat /server/scripts/log.sh sleep1 echo chensiqi >> /server/log/chensiqi.log
定時任務寫法:
* * * * * /bin/sh /server/scripts/log.sh >dev/null 2>&1 定時任務,給定時任務看病的日誌/var/log/cron
- 要領5:在指定用戶下執行相關定時任務
須要root權限執行的任務能夠登陸到root用戶下而後設置,若是不須要root權限,能夠登陸到普通用戶下(也能夠直接在root下crontab -u chensiqi -e 的寫法直接設置),而後設置。這裏要特別注意不一樣用戶的環境變量問題,若是是調用了系統環境變量/etc/profile(如生產場景中java程序的定時任務),最好在程序腳本中將用到的環境變量從新export下(下文有案例)。
-
要領6:生產任務程序不要隨意打印輸出信息。
儘可能關閉取消沒有用的輸出(命令的執行過程)
1,定向到文件
2,>/dev/null 2>&1
在開發定時任務程序或腳本時,在調試好腳本程序後,應儘可能把DEBUG及命令輸出的內容信息屏蔽掉,若是確實須要輸出日誌,可定向到執行日誌文件裏,避免產生系統垃圾。 -
要領7:定時任務命令或程序最好寫到腳本里執行
-
要領8:定時任務執行的腳本要規範路徑
例如:/server/scripts
- 要領9:配置定時任務規範操做過程,防止出錯。
1,首先要在命令行操做成功,而後複製成功的命令到腳本里,在各個細小環節減小出錯的機會。
2,而後測試腳本,測試成功後,複製腳本的規範路徑到定時任務配置裏,不要手敲。
3,先在測試環境下測試,而後正式環境規範部署
小結:
書寫定時任務的若干要領方法:
要領1:爲定時任務規則加必要的註釋。
要領2:執行shell腳本任務前加/bin/sh
要領3:定時任務命令或腳本結尾加>/dev/null 2>&1
要領4:定時任務命令或程序最好寫到腳本里執行
要領5:在指定用戶下執行相關的定時任務
要領6:生產任務程序不要隨意打印輸出信息
要領7:定時任務執行的腳本要規範路徑(/server/scripts)
要領8:配置定時任務規範操做過程
1.1.3 在命令行輸入./chensiqi.sh(/server/scripts/chensiqi.sh)與sh chensiqi.sh區別在哪?
[root@chensiqi1 ~]# cat chensiqi.sh #!/bin/bash echo "chensiqi" [root@chensiqi1 ~]# ll chensiqi.sh -rw-r--r--. 1 root root 29 Feb 10 21:44 chensiqi.sh [root@chensiqi1 ~]# sh chensiqi.sh chensiqi [root@chensiqi1 ~]# ./chensiqi.sh -bash: ./chensiqi.sh: Permission denied [root@chensiqi1 ~]# 命令說明: sh chensiqi.sh表示用/bin/sh這個命令來解析並啓動chensiqi.sh這個腳本。而./chensiqi.sh表示利用linux的默認解釋器來解析並啓動這個腳本。所以,./chensiqi.sh須要linux下x的執行權限,而sh chensiqi.sh不須要。
1.1.4 定時任務不加>/dev/null 2>&1的後果
- 若是定時任務規則結尾不加>/dev/null 2>&1等命令配置,有可能有大量輸出信息,時間長了,可能因爲系統未開啓郵件服務而致使郵件臨時目錄/var/spool/clientmqueue 文件數猛增的隱患發生,大量文件會佔用大量磁盤inode節點(每一個文件佔一個inode),以至磁盤inode滿而沒法寫入正常數據(下文有案例)。
- 提示:上面的>/dev/null 2>&1 寫法也能夠寫成1>/dev/null 2>/dev/null,例:
$JAVA-jar $RESIN_HOME/lib/resin.jar $ARGS stop 1>/dev/null 2>/dev/null
此寫法來自resin服務默認啓動腳本- 上述是centos5.8的狀況,假如系統不安裝sendmail(Centos6.4),那是否是就沒有上述問題了?
企業案例::若是定時任務規則結尾不加>/dev/null 2>&1,很容易致使硬盤inode空間被佔滿,從而系統服務不正常。
當一個定時任務執行的時候,就會給系統發一封郵件。sendmail郵件服務,常常是關閉的,因此定時任務發送的郵件就會臨時堆在/var/spool/clientmqueue/,時間長了,/var/spool/clientmqueue/文件數特別多。Centos5的時候必定會有這個問題。
Centos6呢?請往下看。
[root@chensiqi1 ~]# cat /etc/redhat-release CentOS release 6.8 (Final) [root@chensiqi1 ~]# crontab -l #go to chensiqi trainning by chensiqi at 20170211 * * * * * /bin/sh /root/chensiqi.sh [root@chensiqi1 ~]# ls /var/spool/postfix/maildrop/ D3AD0C6 DB2BAC9 E14E6D0 E5222D1 [root@chensiqi1 ~]# 命令說明: 定時任務沒定向到空,postfix服務沒有開啓的話,那麼每執行一次定時任務,/var/spool/postfix/maildrop/文件夾下就會產生一個小文件,隨着時間累計,就會愈來愈多,致使出現問題。 若是開啓了郵件服務,就會直接給root發送郵件。
解決方法:
1,刪除大量小文件/var/spool/postfix/maildrop/下全部文件(ls|xargs rm -f)
2,臨時開啓postfix(sendmail)服務
3,vi /etc/crontab:將‘MAILTO=root’替換成‘MAILTO=「」’而後service crond restart便可。(若是還不行,crontab -e 第一行增長MAILTO=「」)
亡羊補牢:
定時任務定向到空>/dev/null 2>&1
目錄名 | 解釋 |
---|---|
/var/spool/clientmqueue | centos5.x sendmail臨時郵件文件目錄,有不少緣由會致使這個目錄碎文件不少,好比crontab定時任務命令不加>/dev/null等,而且sendmail服務沒開。工做中偶爾會由於該目錄文件太多,致使/var所在的分區inode數量被消耗盡,沒法寫入文件的狀況 |
/var/spool/postfix/maildrop/ | centos6.x postfix臨時隊列目錄/var/spool/postfix/maildrop/默認定時任務執行時會給root發郵件,若是郵件服務不開,就會把郵件推到上述目錄。當定時任務結尾不加>/dev/null 2>&1的時候,定時任務就會在上述目錄存大量小文件 |
1.2 定時任務的系統配置文件/etc/crontab
[root@chensiqi1 ~]# cat /etc/crontab
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
HOME=/
# For details see man 4 crontabs # Example of job definition: # .---------------- 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 sun,mon,tue,wed,thu,fri,sat # | | | | | # * * * * * user-name command to be executed
SHELL=/bin/bash #shell解釋器
PATH=/sbin:/bin:/usr/sbin:/usr/bin #PATH環境變量
MAILTO=root #定義若是任務有輸出,發給哪一個用戶,默認發給root用戶
HOME=/ #定時任務執行命令從根目錄開始
輪詢的日誌(日誌輪詢):週期性切割日誌
系統的定時任務+logrotate
[root@chensiqi1 ~]# cat /etc/cron.daily/logrotate #!/bin/sh /usr/sbin/logrotate /etc/logrotate.conf EXITVALUE=$? if [ $EXITVALUE != 0 ]; then /usr/bin/logger -t logrotate "ALERT exited abnormally with [$EXITVALUE]" fi exit 0
[root@chensiqi1 ~]ll /var/log/messages* -rw-------. 1 root root 58049 Feb 10 23:18 /var/log/messages -rw-------. 1 root root 1492005 Jan 2 06:51 /var/log/messages-20170102 -rw-------. 1 root root 633737 Jan 8 08:02 /var/log/messages-20170108 -rw-------. 1 root root 1594144 Feb 4 04:25 /var/log/messages-20170204 -rw-------. 1 root root 21512 Feb 6 03:41 /var/log/messages-20170206 [root@chensiqi1 ~]# ll /var/log/secure* -rw-------. 1 root root 4810 Feb 10 22:39 /var/log/secure -rw-------. 1 root root 64822 Jan 2 06:27 /var/log/secure-20170102 -rw-------. 1 root root 14187 Jan 8 07:22 /var/log/secure-20170108 -rw-------. 1 root root 13540 Jan 12 00:17 /var/log/secure-20170204 -rw-------. 1 root root 5723 Feb 6 02:50 /var/log/secure-20170206
1.3 企業生產場景如何調試crontab定時任務
1.3.1 增長執行任務頻率調試任務(某些任務不能用於生產環境)
1,在調試時,把任務執行頻率調快一點,如:每分鐘,每5分鐘執行一次,或者比當前時間推遲5分鐘之後,看可否執行,是否是按照你想象的去執行了,若是正常沒問題了,在改爲須要的任務的執行時間。
強調:有些計劃任務是不容許頻繁執行的,例如:定時往數據庫裏插入數據,這樣的任務就要在測試機上測試好,而後部署到正式線上,這樣正式工做出問題的機會就少了。
規範的公司開發和運維人員操做流程,我的的開發配置環境-->辦公室的測試環境-->idc機房的測試環境-->idc機房的正式環境。
使用log文件調試任務
-
-
-
-
- /bin/sh
/server/scripts/del_sys_file.sh >/tmp/file.log 2>&1
- /bin/sh
-
-
-
1.3.2 調整系統時間調試任務(不能用於生產環境)
如字面意思,調整系統時間,以達到接近觸發計劃任務的目的進行調試。
1.3.3 經過腳本日誌輸出調試定時任務
在腳本中加入日誌輸出,而後把輸出打到指定的日誌中,而後觀察日誌內容結果,看是否執行或正確執行。或像下面的內容把腳本結果定向到一個log文件裏,重定向>便可,不須要>>追加,這樣日誌就不會一直變大,如/app/log.log。
#study task by chensiqi at 20170211 00 09,14 * * 0,6 /bin/sh /server/scripts/chensiqi.sh >/app/log.log 2>&1 也能夠在腳本里面echo 1 >/tmp/a.log
腳本中加輸出
[root@chensiqi ~]# cat tar.sh cd / tar zcvf /tmp/etc_$(date +%Y%m%d%H).tar.gz ./etc >/tmp/tmp.log 2>&1
sh -x 顯示腳本的執行過程
[root@chensiqi ~]# /bin/sh /server/scripts/chensiqi.sh 2017-02-11 [root@chensiqi ~]# /bin/sh -x /server/scripts/chensiqi.sh + date +%F 2017-02-11
1.3.4 注意環境變量致使的定時任務故障
PATH
在調試java程序任務的時候,注意環境變量,把環境變量的定義加到腳本里。
例:
[root@chensiqi ~]# cat /scripts/resin/shell/Task.sh #!/bin/bash export JAVA_HOME=/application/jdk1.6 export PATH=$JAVA_HOME/bin:$PATH export SH_HOME=/application/resin/webapps/ROOT/ export LIB=$SH_HOME/WEB-INF/lib 如下省略... 定時任務: 00 09,14 * * * nohup /scripts/resin/shell/Task.sh & >/app/log.log 2>&1 提示:命令也要儘量寫全路徑。
1.3.5 經過crond定時任務服務日誌調試定時任務
查看定時任務服務日誌
[root@chensiqi1 ~]# tail -f /var/log/cron Feb 10 23:50:01 chensiqi1 CROND[15949]: (root) CMD (/usr/lib64/sa/sa1 1 1) Feb 10 23:53:01 chensiqi1 CROND[15955]: (root) CMD (/usr/lib64/sa/sa2 -A) Feb 11 00:00:01 chensiqi1 CROND[15987]: (root) CMD (/usr/lib64/sa/sa1 1 1) Feb 11 00:01:01 chensiqi1 CROND[15992]: (root) CMD (run-parts /etc/cron.hourly) Feb 11 00:01:01 chensiqi1 run-parts(/etc/cron.hourly)[15992]: starting 0anacron Feb 11 00:01:01 chensiqi1 anacron[16003]: Anacron started on 2017-02-11 Feb 11 00:01:01 chensiqi1 anacron[16003]: Jobs will be executed sequentially Feb 11 00:01:01 chensiqi1 anacron[16003]: Normal exit (0 jobs run) Feb 11 00:01:01 chensiqi1 run-parts(/etc/cron.hourly)[16005]: finished 0anacron Feb 11 00:10:01 chensiqi1 CROND[16008]: (root) CMD (/usr/lib64/sa/sa1 1 1)
1.3.6 其餘稀奇古怪的問題調試的辦法
直接命令行執行無問題而放到定時任務就不行
綜合前邊1-5的方法就能夠解決幾乎全部遇到的問題了,此類問題主要是多看crond服務日誌,而且把程序輸出到指定日誌分析。