項目突然上線了一個測試包,這個程式包老是會突然就死掉,雖然已經打回開發那邊改了,但是服務這邊又不允許回退版本,是以我隻能頂着個爛包來幹活了。zabbix那邊可以監控,但是很多時候我在外面,無法跑回去重新開機,是以打算寫一個簡單的程序守護程式來監控它
資産上有jdk,也有py和go環境,腳本類的程式的話就不用java寫了,python的版本比較低,我也沒有root權限去更新python版本,是以用python來完成這個腳本的話可能會遇到很多不相容的寫法,最後選擇了go來寫
我的思路是:啟動一個程式,每隔20秒列印一次該程序的pid和狀态到日志中,假如檢測不到該程序的pid,則重新啟動該程式。假如檢查到程序狀态為T或Z,就重新啟動該程式。假如檢測到程式日志檔案長時間大小沒有增加,則重新啟動(此步未完成,因為這個程式包的日志正常情況下不持續列印)
為了友善示範,我就随便開個tomcat,來模拟一個程序,先上代碼:
package main
import(
"fmt"
"os/exec"
"bytes"
"time"
"strings"
)
func main() {
for {
var outInfo bytes.Buffer
//用exec.Command來調用linux指令,這條linux指令如果被調用會列印出pid和狀态
cmd := exec.Command("bash", "-c", "ps aux|grep tomcat|grep -v grep|awk '{print $2,$8}'")
//接收輸出
cmd.Stdout = &outInfo
//執行指令
cmd.Run()
output := outInfo.String()
//這裡加個時間,因為要列印到日志裡,沒有時間的話定位不到程式什麼時候斷了
fmt.Print(time.Now().Format("2006-01-02 15:04:05"))
//判斷接收到的輸出值是否為空
if output=="" {
//空的話說明程式沒有啟動,調用下面寫好的啟動函數
startProcess()
}else if status:= strings.Contains(output,"T");status{
reloadProcess()
}else if status:= strings.Contains(output,"Z");status{
reloadProcess()
}else if status:= strings.Contains(output,"X");status{
reloadProcess()
}else{
fmt.Println(":[INFO]tomcat程式存在!")
}
//由于是有執行操作的死循環,來個延時,這裡設定20秒
time.Sleep(time.Duration(20)*time.Second)
}
}
func startProcess(){
var outInfo bytes.Buffer
fmt.Println(":[ERROR]tomca未啟動,正在自動啟動中...")
//這裡調用了啟動tomcat的指令
cmd := exec.Command("bash", "-c", "sh apache-tomcat-8.5.79/bin/startup.sh")
cmd.Stdout = &outInfo
cmd.Run()
fmt.Println(outInfo.String())
}
func reloadProcess(){
var outInfo bytes.Buffer
fmt.Println(":[ERROR]程序狀态異常!正在重新啟動...")
//這裡調用了殺死程序和重新啟動的指令
cmd_stop := exec.Command("bash", "-c", "ps aux|grep |awk '{print $2}'|xargs kill -9")
cmd_start := exec.Command("bash", "-c", "sh apache-tomcat-8.5.79/bin/startup.sh")
cmd_start.Stdout = &outInfo
cmd_stop.Run()
cmd_start.Run()
fmt.Println(outInfo.String())
}
我将它寫成了一個test.go檔案,在終端執行
nohup go run test.go >> run.log 2>&1 &

ps一下這個腳本檔案是否存在
ps aux|grep test.go
可以看到腳本已經跑起來了,現在去日志看看
tail -f -n 100 run.log
可以看到腳本一直在監控着tomcat,現在我們把tomcat程序殺掉,然後再看看情況:
tomcat已經殺掉了,模拟程式停掉的情況,現在傳回日志看看情況:
可以看到日志中檢測到tomcat停止,然後自動把它給啟動了,在ps一下看看tomcat是否已經啟動:
可以看到程序是在的,頁面也可以正常打開。
#!/bin/bash
log=/data/log/access.log
N=30 #設定門檻值
while true
do
#檢視通路日志的最新300條,并統計502的次數
err=`tail -n 300 $log |grep -c '502" '`
#如果日志中出現502的次數大于我們設定的門檻值
if [ $err -ge $N ]
then
/etc/init.d/php-fpm restart 2> /dev/null
#設定60s延遲防止腳本bug導緻無限重新開機php-fpm服務
sleep 60
fi
sleep 10
done