現(xiàn)在我們會(huì)發(fā)現(xiàn)很多個(gè)人站長(zhǎng)的博客都會(huì)有不定時(shí)的打不開,要不是mysql數(shù)據(jù)庫停止了,要么是nginx 502了或者apache不運(yùn)行了,為了防止網(wǎng)站出現(xiàn)此問題我們給各位整理了一些監(jiān)控這些服務(wù)是不是正常工作的代碼,希望可幫助大家.
前幾天發(fā)現(xiàn)網(wǎng)站打不開,提示數(shù)據(jù)庫連接錯(cuò)誤,我登錄linux 發(fā)現(xiàn)mysqld服務(wù)不知道什么時(shí)候停止了,幸好我即使發(fā)現(xiàn).
于是決定寫一個(gè)shell腳本每分鐘自動(dòng)檢測(cè)mysqld服務(wù),如果發(fā)現(xiàn)服務(wù)沒起來就自動(dòng)啟動(dòng)mysqld服務(wù),也就是:通過cron定時(shí)任務(wù)執(zhí)行檢測(cè)腳本.
編寫檢測(cè)腳本 /root/bin/check,代碼如下:
- #!/bin/bash
- check=`pgrep mysql`
- if [ -n "$check" ]; then
- exit
- else
- date=$(date +"%Y-%m-%d %H:%M:%S")
- /etc/init.d/mysqld start //Vevb.com
- echo 'error: mysqld at ' $date
- fi
說明:也可以修改check=`pgrep mysql` 比如 check=`pgrep httpd` 或者 check=`pgrep nginx`來監(jiān)測(cè)其他服務(wù),
編輯cron執(zhí)行:crontab -e
cron內(nèi)容如下,其中注釋掉了一行,可選擇性編寫.
#* * * * * sh /root/bin/check > /dev/null 2>&1 #執(zhí)行后不發(fā)送結(jié)果郵件
* * * * * sh /root/bin/check >> /root/bin/log.txt #執(zhí)行后發(fā)送結(jié)果到指定文件
由于cron每次執(zhí)行后如果有輸出則會(huì)默認(rèn)發(fā)送郵件到 /var/spool/mail/root 長(zhǎng)時(shí)間會(huì)導(dǎo)致 此文件有很多無用記錄,我們可以用 > /dev/null 2>&1 忽略結(jié)果寫入,當(dāng)然也可以用 >> /root/bin/log.txt 寫入到指定文件(要事先建立好文件).
cron命令行簡(jiǎn)要說明:
- 分 時(shí) 日 月 星期 命令行
- 例: */5 * * * * cmd #表示每5分鐘執(zhí)行一次命令
- command > filename 把標(biāo)準(zhǔn)輸出重定向到一個(gè)新文件中
- command >> filename 把標(biāo)準(zhǔn)輸出重定向到一個(gè)文件中(追加)
- command 1 > fielname 把標(biāo)準(zhǔn)輸出重定向到一個(gè)文件中
- command > filename 2>&1 把標(biāo)準(zhǔn)輸出和標(biāo)準(zhǔn)錯(cuò)誤一起重定向到一個(gè)文件中
- command 2 > filename 把標(biāo)準(zhǔn)錯(cuò)誤重定向到一個(gè)文件中
- command 2 >> filename 把標(biāo)準(zhǔn)輸出重定向到一個(gè)文件中(追加)
- command >> filename 2>&1 把標(biāo)準(zhǔn)輸出和標(biāo)準(zhǔn)錯(cuò)誤一起重定向到一個(gè)文件中(追加)
- command < filename >filename2 把command命令以filename文件作為標(biāo)準(zhǔn)輸入,以filename2文件作為標(biāo)準(zhǔn)輸出
- command < filename 把command命令以filename文件作為標(biāo)準(zhǔn)輸入
- command << delimiter 把從標(biāo)準(zhǔn)輸入中讀入,直至遇到delimiter分界符
- command <&m 把文件描述符m作為標(biāo)準(zhǔn)輸入
- command >&m 把標(biāo)準(zhǔn)輸出重定向到文件描述符m中
- command <&- 把關(guān)閉標(biāo)準(zhǔn)輸入
- command 2>&1 把command命令標(biāo)準(zhǔn)錯(cuò)誤重定向到標(biāo)準(zhǔn)輸出
下面的shell通過一個(gè)while-do循環(huán),用ps -ef|grep 檢查loader進(jìn)程是否正在運(yùn)行,如果沒有運(yùn)行,則啟動(dòng),這樣就保證了崩潰掛掉的進(jìn)程重新被及時(shí)啟動(dòng).
必須注意兩點(diǎn):
1、ps |grep 一個(gè)進(jìn)程時(shí)必須加上其路勁,否則容易grep到錯(cuò)誤的結(jié)果.
2、必須用 -v 從結(jié)果中去除grep命令自身,否則結(jié)果非空,代碼如下:
- #!/bin/sh
- #=====================
- #Vevb.com
- #khler@163.com
- #=====================
- while :
- do
- echo "Current DIR is " $PWD
- stillRunning=$(ps -ef |grep "$PWD/loader" |grep -v "grep")
- if [ "$stillRunning" ] ; then
- echo "TWS service was already started by another way"
- echo "Kill it and then startup by this shell, other wise this shell will loop out this message annoyingly" //Vevb.com
- kill -9 $pidof $PWD/loader
- else
- echo "TWS service was not started"
- echo "Starting service ..."
- $PWD/loader
- echo "TWS service was exited!"
- fi
- sleep 10
- done
如果啟動(dòng)此shell時(shí)發(fā)現(xiàn)進(jìn)程已經(jīng)存在,說明以別的方式啟動(dòng)了進(jìn)程而不是此shell,那么它會(huì)持續(xù)提醒找到進(jìn)程,解決辦法是,要么只用此shell啟動(dòng)服務(wù),要么一經(jīng)發(fā)現(xiàn)以其他方式啟動(dòng)的服務(wù)即kill掉,上面的語句就是這么干的:
kill -9 $pidof $PWD/loader
再補(bǔ)充一個(gè)監(jiān)控nginx的shell腳本
Nginx 雖然處理并發(fā)量比 apache 確實(shí)要強(qiáng)點(diǎn),但它這種 php-cgi 模式不是太穩(wěn)定,這點(diǎn)網(wǎng)上也有朋友總結(jié)了,我在實(shí)現(xiàn)項(xiàng)目中也感受到了。
我們一臺(tái)支付機(jī),偶爾會(huì)出現(xiàn)以下情況的:php-cgi 進(jìn)程突然消失了,造成PHP腳本無法訪問;更不可思議的是明明是php-cgi 打開有兩個(gè)端口在監(jiān)聽的,莫名其秒的突然有一個(gè)php-cgi 的端口被關(guān)閉了,造成所有請(qǐng)求全積在一個(gè)端口上,結(jié)果造成PHP腳本訪問異常。
基本這種情況,我寫了個(gè)監(jiān)控shell腳本的解決方案,不管以上出現(xiàn)那種情況,都自動(dòng)恢復(fù)Nginx的服務(wù).該腳本在生產(chǎn)環(huán)境上運(yùn)行正常,代碼如下:
- #!/bin/bash
- #
- # filename: webservermonitor.sh
- # 功能:監(jiān)控 nginx 的 php-cgi 是否正常
- # 作者:V哥
- # 運(yùn)行: webservermonitor.sh &
- #
- # php-cgi 監(jiān)聽的IP和端口
- V_PHP_CGI_PORT="127.0.0.1:9000 127.0.0.1:9001"
- # nginx重啟的腳本
- V_NGINX="/usr/local/nginx/sbin/restart.sh"
- # 日志文件
- V_LOG="/tmp/webservermonitor.log"
- # 函數(shù)定義:重啟nginx
- function restart_nginx(){
- echo "----- `date` -----" >> $V_LOG
- echo "------------------" >> $V_LOG
- echo "`ps aux |grep 'nginx'`" >> $V_LOG
- echo "------------------" >> $V_LOG
- echo "`ps aux |grep 'php-cgi'`" >> $V_LOG
- echo "------------------" >> $V_LOG
- echo "`netstat -nlpt | grep 'php-cgi'`" >> $V_LOG
- echo "------------------" >> $V_LOG
- $V_NGINX >> $V_LOG
- }
- # 循環(huán)執(zhí)行,不采用 crontab ,國為 crontab 最小單位是分鐘,時(shí)間太長(zhǎng)了
- while :
- do
- # 1:先檢測(cè) nginx 主進(jìn)程是否存在
- V_NGINX_NUM=`ps axu |grep 'nginx' |grep -v 'grep' |wc -l`
- if [ $V_NGINX_NUM -lt 1 ];then
- restart_nginx
- continue
- fi
- # 2:再檢查php-cgi是否有進(jìn)程存在
- V_PHP_CGI_NUM=`ps axu |grep 'php-cgi' |grep -v 'grep' |wc -l`
- if [ $V_PHP_CGI_NUM -lt 1 ];then
- restart_nginx
- continue
- fi
- # 3:再判斷端口是否正常
- for PORT in $V_PHP_CGI_PORT
- do
- V_NUM=`eval "netstat -nlpt | grep '${PORT}' | wc -l"`
- if [ $V_NUM -lt 1 ];then
- restart_nginx
- continue
- fi
- done
- # 休眠
- sleep 5
- done
ps:當(dāng)然現(xiàn)在有一些服務(wù)器也提供方法像dnspod就提供了域名監(jiān)控功能,可以監(jiān)控到服務(wù)器是否正常哦.
新聞熱點(diǎn)
疑難解答
圖片精選