这两天做了一个服务监控报警重启的脚本。本质就是用一个shell命令去监控服务状态,如果宕机就会自动重启,并向指定邮箱发送邮件对管理人员进行提醒,再使用crontab命令设置每隔一分钟运行一次这个shell脚本,实现对服务的监控。
本来很简单,以为半天就能实现,结果问题出在了发送邮件上,硬生生的搞了两天,才在部门其他大神的帮助下搞定,所以在此总结下。
首先先写一个简单的监控服务的shell脚本,公司在服务器上跑的是以jar包的形式,为了方便测试,我就随便找了一个jar包,命名为1.jar
直接新建编辑一个moni.sh 脚本文件
vi moni.sh
在moni.sh中进行编辑
run=$(ps -ef |grep "1.jar" |grep -v "grep")
if [ "$run" ] ; then
echo "The service is alive!"
else
echo "系统宕机" | mail -s "警告" 2364******@qq.com #接收人邮箱地址
echo "The service was shutdown!"
echo "Starting service ..."
nohup java -jar 1.jar &
echo "The service was started!"
fi
再对crontab命令进行设置
crontab -e
直接会进入编辑页面,输入以下代码设置间隔时间自动运行
*/1****bash /home/wangzh/moni.sh #设置为每间隔1分钟执行一次脚本
@reboot nohup java -jar 1.jar & #每当系统重启时都会自动运行服务
linux发送邮件很简单,它自带有发送邮件的mail,一开始我使用mail进行发送邮件发现不成功;就想通过linux的sendmail来发送,这个需要使用yum下载sendmail的rpm包,且配置十分麻烦,最后由于种种原因放弃了,回归linux自带的mail发送邮件方式。
首先,要对 etc 下的 mail.rc进行编辑
vim /etc/mail.rc
进入编辑页面后,在其中添加以下配置信息
set [email protected] #对方收到邮件后显示的发送人
set smtp=smtp.126.com#你发送邮件的邮箱服务器地址
set [email protected]#发件人的邮箱
set smtp-auth-password=xxx#开启你邮箱中运行第三方发送的授权码,填写授权码
set smtp-auth=login
保存退出后,输入以下发送邮件命令进行测试
(我的个人经验,主题不要用英文,内容不限但不能写test,容易被当成垃圾邮件直接被第三方邮件服务器拦截)
echo "邮件内容" | mail -s "邮件主题" 2364600***@qq.com #邮箱为接收人邮箱,邮箱服务器地址跟你发件人邮箱有关,接收人邮箱并无限制
到此基本功能都实现了。但问题出在了发送邮件上面。发送邮件屡次不成功,一开始执行命令后,不弹出错误信息,也收不到邮箱,后来开始报 timed out,也报过一些诸如535这样的错误代码,中间排除了许多可能,最后把错误定位到端口号上。
首先,linux的发送邮件端口默认的是25,。而我们公司是在阿里云服务上运行的,阿里云默认把发邮件的25端口给禁了,好像是怕不安全。然后,我们就只能使用阿里云提供的另外的邮件端口:使用TSL加密协议,也就是465端口。
TSL也就是使用SSL加密的方式,使用465或者其他端口来发送邮件,现在大部分邮箱都支持SSL,具体SSL的端口 地址,也可以查百度,我使用的是163邮箱是465端口。既然使用的是SSL协议,那当然是要有证书的了,下面是获取证书的命令:
先创建一个证书的存放目录(.cert加了一个.是隐藏目录的意思,具体需不需要隐藏,我也不知道,网上教程使用的隐藏)
mkdir -p /home/wangzh/.certs/ //放到绝对路径下
再以此输入以下命令:
echo -n | openssl s_client -connect smtp.163.com:465 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > ~/.certs/qq.crt #如果你使用的是其他邮箱,这里需要你自己改成其他的邮箱服务器地址和端口号
certutil -A -n "GeoTrust SSL CA" -t "C,," -d ~/.certs -i ~/.certs/qq.crt
certutil -A -n "GeoTrust Global CA" -t "C,," -d ~/.certs -i ~/.certs/qq.crt
certutil -L -d /home/wangzh/.certs
命令执行完毕后,如果不报错,就会看到以下文件:
然后有了证书文件,我们还需要在etc/mail.rc中编辑代码获取证书文件
vim /etc/mail.rc
在mail.rc中添加以下代码:
set ssl-verify=ignore
set nss-config-dir=/home/wangzh/.certs #这个路径是你自己的certs存放的路径
保存退出。一切ok!
一般买的云服务器上都会自带有cron的
但是如果没有安装的话,分别执行下边两个命令进行安装
yum -y install vixie-cron
yum -y install crontabs
安装好了以后,可以通过以下命令开启、关闭定时任务,以及查看crontab的状态
service crond start //启动服务
service crond stop //关闭服务
service crond restart //重启服务
service crond reload //重新载入配置
service crond status //查看crontab服务状态
开启定时任务服务后 用这个命令 service crond status 来查看一下
可以看到已经启动了
以下是我服务器上的一个服务的定时任务的脚本内容:仅供参考
#--------------------------------------------------------------------------------------
#查询wx_pay进程个数:wc -l 返回行数
count=`ps -ef | grep wx_pay-0.0.1-SNAPSHOT.jar | grep -v "grep" | wc -l`
#echo $count
sec=7
nowtime=`date +"%Y-%m-%d %H:%M:%S"`
nowDate=`date +"%Y-%m-%d"`
#开始一个循环,以判断进程是否关闭
for var in 1 2
do
if [ $count -gt 0 ]; then
#若进程还未关闭,则脚本sleep几秒
echo sleep $sec second the $var time, the wx_pay_Thread is still alive
sleep $sec
else
#若进程已经关闭,则重启,并出循环
cd /cj/wxpay
nohup java -jar wx_pay-0.0.1-SNAPSHOT.jar > nohup.log 2&>wx_pay-$nowDate.log &
echo $nowtime" start wx_pay-0.0.1-SNAPSHOT.jar"
echo "ok! is success!"
echo ""
break
fi
done
#--------------------------------------------------------------------------------------
输入命令:crontab -e
把定时任务脚本添加进去
#一分钟检查一次,然后把重新启动的日志追加至restart.log中
*/1 * * * * /cj/wxpay/wx_pay_restart.sh >> /cj/wxpay/restart.log
如果当前的服务进程没有挂掉,它会打印出
sleep 7 second the 1 time, the wx_pay_Thread is still alive
然后7秒以后会再次去尝试着看下进程是否存活,如果还是存活就打印出
sleep 7 second the 2 time, the wx_pay_Thread is still alive
然后进入下一次定时任务的轮询
然后咱们把对应的服务kill掉以后,来看一下它会不会自动重启
可以看到当前的服务已经被kill掉了,是没有启动的
一分钟左右(我设置的cron任务是一分钟执行一次)定时任务执行后,再看下。
可以看到定时任务执行后,打印出了启动成功!
再 ps 看一下对应的服务是否启动了,可以看到对应的服务已经启动了。
这样就实现了服务宕机挂掉后,自动检测并自动重启