1. 程式人生 > >Linux實戰教學筆記13:定時任務補充

Linux實戰教學筆記13:定時任務補充

第十三節 定時任務補充

標籤(空格分隔): Linux實戰教學筆記

---[更多資料點我檢視][1]

1,生產環境常用Crontab專業例項

1.1書寫crontab定時任務多個基本要領

1.1.1 規範定時任務兩例

例1:每分鐘列印一次自己的名字拼音全拼到“/server/log/自己的名字命名的檔案”中。

[[email protected] ~]# mkdir -p /server/log/
[[email protected] ~]# echo "chensiqi" >>/server/log/chensiqi
[[email protected]
~]# cat /server/log/chensiqi chensiqi [[email protected] ~]# crontab -e crontab: installing new crontab [[email protected] ~]# crontab -l ##print name to file * * * * * /bin/echo "chensiqi" >>/server/log/chensiqi [[email protected] ~]#

解答:
方法1:

#print my name to log by chensiqi at 2017211
* * * * * /bin/echo "chensiqi" >>/server/log/chensiqi

方法2

#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/cron

例2:每週六,日上午9點和下午14點(執行/server/scripts/chensiqi.sh).要求:/server/scripts/chensiqi.sh指令碼的功能是列印當天的日期:格式為2017-02-11可以隨意。

解答:

##
00 9,14 * * 0,6 /bin/sh /server/scripts/chensiqi.sh >/dev/null 2>&1

步驟:

  • 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

技巧:

  1. 定時任務一定要儘量用指令碼實現。
  2. 命令列操作成功,然後放入指令碼執行(/bin/sh 指令碼全路徑)成功,最後在配置任務
  3. 複製操作成功的命令列指令碼,再定時任務裡黏貼配置。
  4. 加/bin/sh執行指令碼 /bin/sh /server/script/chensiqi.sh
  5. 要把指令碼的執行結果定向到空或者是一個檔案中,不要什麼都不加。

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

標準寫法:

[[email protected] /]# 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區別在哪?

 [[email protected] ~]# cat chensiqi.sh
 #!/bin/bash

echo "chensiqi"
[[email protected] ~]# ll chensiqi.sh
-rw-r--r--. 1 root root 29 Feb 10 21:44 chensiqi.sh
[[email protected] ~]# sh chensiqi.sh
chensiqi
[[email protected] ~]# ./chensiqi.sh
-bash: ./chensiqi.sh: Permission denied
[[email protected] ~]# 

命令說明:
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呢?請往下看。

[[email protected] ~]# cat /etc/redhat-release 
CentOS release 6.8 (Final)
[[email protected] ~]# crontab -l 
#go to chensiqi trainning by chensiqi at 20170211
* * * * * /bin/sh /root/chensiqi.sh
[[email protected] ~]# ls /var/spool/postfix/maildrop/
D3AD0C6  DB2BAC9  E14E6D0  E5222D1
[[email protected] ~]# 

命令說明:
定時任務沒定向到空,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.xsendmail臨時郵件檔案目錄,有很多原因會導致這個目錄碎檔案很多,比如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

[[email protected] ~]# 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

[[email protected] ~]# 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
[[email protected] ~]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
[[email protected] ~]# 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

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
指令碼中加輸出
[[email protected] ~]# cat tar.sh
cd /
tar zcvf /tmp/etc_$(date +%Y%m%d%H).tar.gz ./etc >/tmp/tmp.log 2>&1

sh -x 顯示指令碼的執行過程

[[email protected] ~]# /bin/sh /server/scripts/chensiqi.sh
2017-02-11
[[email protected] ~]# /bin/sh -x /server/scripts/chensiqi.sh
+ date +%F
2017-02-11

1.3.4 注意環境變數導致的定時任務故障

PATH
在除錯java程式任務的時候,注意環境變數,把環境變數的定義加到腳本里。
例:

[[email protected] ~]# 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定時任務服務日誌除錯定時任務

檢視定時任務服務日誌

[[email protected] ~]# 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服務日誌,並且把程式輸出到指定日誌分析。

第十三節 定時任務補充

標籤(空格分隔): Linux實戰教學筆記

---[更多資料點我檢視][1]

1,生產環境常用Crontab專業例項

1.1書寫crontab定時任務多個基本要領

1.1.1 規範定時任務兩例

例1:每分鐘列印一次自己的名字拼音全拼到“/server/log/自己的名字命名的檔案”中。

[[email protected] ~]# mkdir -p /server/log/
[[email protected] ~]# echo "chensiqi" >>/server/log/chensiqi
[[email protected] ~]# cat /server/log/chensiqi 
chensiqi
[[email protected] ~]# crontab -e
crontab: installing new crontab
[[email protected] ~]# crontab -l
##print name to file
* * * * * /bin/echo "chensiqi" >>/server/log/chensiqi
[[email protected] ~]# 

解答:
方法1:

#print my name to log by chensiqi at 2017211
* * * * * /bin/echo "chensiqi" >>/server/log/chensiqi

方法2

#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/cron

例2:每週六,日上午9點和下午14點(執行/server/scripts/chensiqi.sh).要求:/server/scripts/chensiqi.sh指令碼的功能是列印當天的日期:格式為2017-02-11可以隨意。

解答:

##
00 9,14 * * 0,6 /bin/sh /server/scripts/chensiqi.sh >/dev/null 2>&1

步驟:

  • 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

技巧:

  1. 定時任務一定要儘量用指令碼實現。
  2. 命令列操作成功,然後放入指令碼執行(/bin/sh 指令碼全路徑)成功,最後在配置任務
  3. 複製操作成功的命令列指令碼,再定時任務裡黏貼配置。
  4. 加/bin/sh執行指令碼 /bin/sh /server/script/chensiqi.sh
  5. 要把指令碼的執行結果定向到空或者是一個檔案中,不要什麼都不加。

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

標準寫法:

[[email protected] /]# 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區別在哪?

 [[email protected] ~]# cat chensiqi.sh
 #!/bin/bash

echo "chensiqi"
[[email protected] ~]# ll chensiqi.sh
-rw-r--r--. 1 root root 29 Feb 10 21:44 chensiqi.sh
[[email protected] ~]# sh chensiqi.sh
chensiqi
[[email protected] ~]# ./chensiqi.sh
-bash: ./chensiqi.sh: Permission denied
[[email protected] ~]# 

命令說明:
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呢?請往下看。

[[email protected] ~]# cat /etc/redhat-release 
CentOS release 6.8 (Final)
[[email protected] ~]# crontab -l 
#go to chensiqi trainning by chensiqi at 20170211
* * * * * /bin/sh /root/chensiqi.sh
[[email protected] ~]# ls /var/spool/postfix/maildrop/
D3AD0C6  DB2BAC9  E14E6D0  E5222D1
[[email protected] ~]# 

命令說明:
定時任務沒定向到空,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.xsendmail臨時郵件檔案目錄,有很多原因會導致這個目錄碎檔案很多,比如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

[[email protected] ~]# 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

[[email protected] ~]# 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
[[email protected] ~]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
[[email protected] ~]# 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

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
指令碼中加輸出
[[email protected] ~]# cat tar.sh
cd /
tar zcvf /tmp/etc_$(date +%Y%m%d%H).tar.gz ./etc >/tmp/tmp.log 2>&1

sh -x 顯示指令碼的執行過程

[[email protected] ~]# /bin/sh /server/scripts/chensiqi.sh
2017-02-11
[[email protected] ~]# /bin/sh -x /server/scripts/chensiqi.sh
+ date +%F
2017-02-11

1.3.4 注意環境變數導致的定時任務故障

PATH
在除錯java程式任務的時候,注意環境變數,把環境變數的定義加到腳本里。
例:

[[email protected] ~]# 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定時任務服務日誌除錯定時任務

檢視定時任務服務日誌

[[email protected] ~]# 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