一次定時任務配置錯誤引發的思考

pikalu發表於2019-10-16

背景

某業務人員反應系統登陸不上去,於是程式設計師自己試著登陸系統成功了,心裡很自信的認為“我的程式碼沒有問題”,便讓業務人員再試試。然後業務人員是登陸成功了,但是整個系統用起來很卡,這下程式設計師意識到是系統的問題了。

排查步驟

因為剛剛上線了新的功能,想到了配置了定時任務,可能是定時任務配置錯誤,導致PHP啟了過多程式。

使用命令ps -ef | grep php 檢視,果然是起了很多沒必要的更新資料指令碼,其中涉及到與第三方介面的互動並且有大量的更新資料庫的操作,所以直接導致系統卡頓。

使用命令crontab -l檢視crontab配置,有幾個指令碼的執行頻率是想配置成每小時執行一次,結果配置錯誤,導致每分鐘執行一次。具體如下:

# 錯誤配置
* */1 * * * /usr/local/bin/php /data/site/demo/yii demo/sync-product

# 正確配置
0 */1 * * * /usr/local/bin/php /data/site/demo/yii demo/sync-product

問題是排查到了,現在需要做的就是快速kill掉那些沒必要的程式。這時候便想到了萬能的awk命令,如下:

ps -ef | grep php | awk '{print $2}' | xargs kill -9

執行後,系統開始恢復穩定。

思考

整個問題排查總結下來,歸根結底還是配置crontab是不夠細心。

同時也引發了其他的一些思考,總結後整理如下:

系統突然出現卡頓,常用的排查思路有哪些呢?

  1. 檢視記憶體使用狀況:free -g
  2. 檢視磁碟使用狀況:df -h
  3. 檢視磁碟I/O使用:iostat -dx
  4. 檢視CPU使用:top

具體的系統調優,本文不做介紹了。

awk命令的基本使用

常用命令

awk '條件型別 1{動作1} 條件型別2{動作2} ...' filename

awk後面接兩個引號並加上大括號來設定想要對資料進行的處理動作。

例如:我們要取出賬號與登入者的IP,且之間以[TAB]隔開,則:

[release@api_02 ~]$ last -n 5 | awk '{print $1 "\t" $3}'
release 117.111.111.11
release 117.111.111.11
release 117.111.111.11
release 117.111.111.11
release 117.111.111.11

awk還存在一些內建變數

變數名稱 代表意義
NF 每一行擁有的欄位總數
NR 目前awk處理的是第幾行
FS 目前的分隔符,預設為空格鍵

繼續上面的例子,需求為:

  • 列出每一行的賬號
  • 列出目前處理的行數
  • 說明該行有多少欄位
[release@api_02 ~]$ last -n 5 | awk '{print $1 "\t lines:" NR "\t columns:"NF}'
release  lines:1     columns:10
release  lines:2     columns:10
release  lines:3     columns:10
release  lines:4     columns:10
release  lines:5     columns:10

awk命令還有更多高階的功能,此處就不做介紹了。

crontab配置的基本使用

crontab配置的規則是:

minute   hour   day   month   week   command

其中每個欄位的含義如下:

minute: 分鐘,取值範圍:0-59之間的整數

hour:小時,取值範圍:0-23之間的整數

day:日期,取值範圍:1-31之間的整數

month:月份,取值範圍:1-12之間的整數

week:星期幾,取值範圍:0-7之間的整數,這裡的0或7代表星期日

command:要執行的命令,可以是系統命令,也可以是自己編寫的指令碼檔案。

特殊字元:

星號(*):表示所有值

逗號(,):可以用逗號隔開的值指定一個列表範圍,例如,“1,2,6,7”

中槓(-):可以用整數之間的中槓表示一個整數範圍,例如“1-3”表示“1,2,3”

正斜線(/):可以用正斜線指定時間的間隔頻率,例如“0-23/2”表示每兩小時執行一次。同時正斜線可以和星號一起使用,例如*/10,如果用在minute欄位,表示每十分鐘執行一次。

常用的一些例子

例項1:每1分鐘執行一次command
命令:
* * * * * command

例項2:每小時的第3和第15分鐘執行
命令:
3,15 * * * * command

例項3:在上午8點到11點的第3和第15分鐘執行
命令:
3,15 8-11 * * * command

例項4:每隔兩天的上午8點到11點的第3和第15分鐘執行
命令:
3,15 8-11 */2 * * command

例項5:每個星期一的上午8點到11點的第3和第15分鐘執行
命令:
3,15 8-11 * * 1 command

例項6:每晚的21:30重啟smb 
命令:
30 21 * * * /etc/init.d/smb restart

例項7:每月1、10、22日的4 : 45重啟smb 
命令:
45 4 1,10,22 * * /etc/init.d/smb restart

例項8:每週六、週日的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

參考資料

linux卡頓怎麼排查

《Linux鳥哥的私房菜基礎學習第三版--12.4.2章節》

原文連結

https://tsmliyun.github.io/2019/10/16/一次定時任務配置錯誤引發的思考/

本作品採用《CC 協議》,轉載必須註明作者和本文連結

不積跬步,無以至千里;不積小流,無以成江海

相關文章