1. 程式人生 > >記一次使用crontab計劃任務執行python指令碼所遇問題及處理的過程

記一次使用crontab計劃任務執行python指令碼所遇問題及處理的過程

今天把一個python指令碼遷移到Centos7,用crontab執行,期間遇到很多錯誤,最終把所遇問題一一處理,感覺有必要把處理過程記錄下來

1、問題環境

  • Centos7 x64
  • python2.7 和python 3.5
  • 有安裝virtualenvwrapper虛擬環境

2、問題描述

  • 此python指令碼的功能是訪問一個固定網站(刷賬號積分,沒啥大用,娛樂玩的),需要持續執行,由於某些原因,指令碼會不定期的出現訪問故障。針對此故障,可以通過優化指令碼的方式來處理,還有一種方式是當出現故障時kill掉相關程序並重新執行指令碼。我選擇的是第二種處理方式,思路是每天在固定時間先kill掉之前的相關程序,然後執行指令碼。
    crontab -l
    類似於下面這樣:
46 5 * * *  /bin/sh /root/sh_dir/shua_ra2jifen.sh 

shua_ra2jifen.sh的內容如下:

#!/usr/bin/sh
ps -ef|grep shua_ra2_jinqian.py|awk '{print $2}'|xargs kill -9
sleep 2
cd ~/.virtualenvs/shuafangwenliang/shua_ra2_jinqian/
workon shuafangwenliang
for ((i=1; i<=10; i++))
do
        nohup python shua_ra2_jinqian.
py & done

3、故障描述

  • 故障1、crontab -e設定指定時間,到指定時間後,指令碼不執行,檢視cron日誌,無內容,檢視nohup日誌,無內容。
    經過好長時間的嘗試才找到問題原因,centos7系統是執行在vultr上的VPS,系統時間是美國當地的時間,而我設定的時間是按照本地筆記本系統上的時間來設定的,中間相差8個小時,而且本地筆記本的時間比北京時間晚了差不多一分鐘的時間,為了方便測試,設定的計劃任務的時間都是比現在時間延後一分鐘,例如現在筆記本的時間是早上9點10分(其實真實的北京時間是9點12分,美國時間是1點12分),我在centos7設定的任務時間是早上1點11分執行,才導致測試失敗。
  • 故障2、修正好故障1的情況後,cron報錯誤日誌,顯示python指令碼中有中文字元的地方語法錯誤。單獨在虛擬環境中執行shua_ra2_jinqian.py指令碼或者shua_ra2jifen.sh指令碼是沒問題的。
    在網上查詢資料後,在crontab中新增LANG=zh_CN.UTF-8,依然有相同的錯誤,無奈只好把python指令碼中的中文字元部分給改掉,再次新增crontab計劃任務,檢視cron報錯日誌顯示缺少urllib2模組,這個錯誤倒是讓問題一下明朗了起來,排查思路轉到是否為python路徑錯誤的問題,於是在shua_ra2jifen.sh指令碼中第一行新增語句#!/usr/bin/python2.7,在shua_ra2_jinqian.py指令碼第一行新增語句:#!/usr/bin/env python,修改crontab計劃任務時間重新執行,檢視cron日誌問題依然如舊,也就是說上述方法不好使。左思右想後,把shua_ra2jifen.sh指令碼中執行python指令碼的語句指定了python的路徑,內容如下:
#!/usr/bin/sh
ps -ef|grep shua_ra2_jinqian.py|awk '{print $2}'|xargs kill -9
sleep 2
cd ~/.virtualenvs/shuafangwenliang/shua_ra2_jinqian/
workon shuafangwenliang
for ((i=1; i<=10; i++))
do
        nohup /usr/bin/python2.7 shua_ra2_jinqian.py &
done

這樣指令碼就成功執行了,再次檢視cron日誌,還是有一條錯誤,顯示無workon命令,於是在搜尋引擎輸入關鍵字“crontab workon”,對指令碼做了如下修改,併成功解決了問題。
shua_ra2jifen.sh

#!/usr/bin/sh

ps -ef|grep shua_ra2_jinqian.py|awk '{print $2}'|xargs kill -9
sleep 2
cd ~/.virtualenvs/shuafangwenliang/shua_ra2_jinqian/
source ../bin/activate
for ((i=1; i<=10; i++))
do
        nohup python shua_ra2_jinqian.py &
done

crontab -e每小時執行一次

0 * * * *  export LANG="en_US.UTF-8"; /bin/sh /root/sh_dir/shua_ra2jifen.sh >/root/a.log 2>&1

4、針對以上兩個問題做一個總結:

  • 第一個問題是由於crontab執行時間設定有誤,有過這樣的經歷後下次再有類似的問題就可以快速的鎖定問題並排除。
  • 第二個問題,問題根本原因是想當然的在crontab計劃任務中執行sh指令碼,讓目錄切換到虛擬環境目錄,用workon執行虛擬環境,執行虛擬環境中的特定python版本,然而,crontab不能呼叫workon命令,開啟不了虛擬環境,也就執行不了特定版本的python,導致後續一系列的問題,例如python中文字元的問題、模組不能載入的問題等等,針對此問題,可以先cd到虛擬環境的bin目錄,然後執行source activate即可開啟虛擬環境。