生产服务器的项目,有时会因为某种因素而崩掉。如docker内存超限导致容器崩溃(前不久就遇过...),又如服务器内存不足或IO读写异常而崩溃等等。而这些原因,都可能影响到项目的正常运行,严重地将会被kill掉。那么,在服务器上弄一套进程监控方案就显得很有必要了!
进程监控采用shell脚本的形式,结合日常开发使用的CI工具(如Jenkins),再通过Linux服务器的定时器,定时监控进程,当进程被killed,服务自动重启。
Jenkins 是一个开源项目,提供了一种易于使用的持续集成系统,使开发者从繁杂的集成中解脱出来,专注于更为重要的业务逻辑实现上。同时 Jenkins 能实施监控集成中存在的错误,提供详细的日志文件和提醒功能,还能用图表的形式形象地展示项目构建的趋势和稳定性。
Jenkins新建一个需持续集成的项目,然后配置从git拉取源码,通过执行shell脚本打包到Linux服务器运行。
注:Install Jenkins的过程暂不在本篇介绍,若有时间,会整理出来。
PROJECT=online_store MOD=cms PORT=9065 IP=xxx ssh root@yyy sh -xe deploy-production.sh $PROJECT $JOB_NAME $MOD $PORT $IP 复制代码
解析:
xxx:根据需要传该参数,如远程打包到不同服务器上,内网 or 公网,对传输都会有影响,涉及的东西与本篇侧重点不一样,故不作拓展
yyy:这个IP务必是 deploy-production.sh
脚本所在的服务器,至关重要,影响着打包及进程监控,可理解为Jenkins持续集成到Linux服务器的入口
注:初始脚本,言下之意是Jenkins与Linux服务器交互的第一个脚本,其余操作包括监控都与初始脚本息息相关。
由于脚本涉及部分隐私,故不全贴出来,仅贴关键部分。
PROJECT=$1 JOB=$2 MOD=$3 PORT=$4 IP=$5 复制代码
nohup /usr/bin/java -jar -Dsun.jnu.encoding=UTF8 -Dfile.encoding=UTF8 -Dspring.profiles.active=production,swagger$MOD $JOB.jar >> /dev/null 2>&1 & 复制代码
sh ~/monitor_exec.sh $PROJECT $JOB $MOD $PORT 复制代码
即执行 monitor_exec.sh
脚本。
作用:将监控脚本写入定时器。
关键代码:
#!/bin/sh PROJECT=$1 JOB=$2 MOD=$3 PORT=$4 mkdir -p ~/cron/ touch ~/cron/$PROJECT.cron file=~/cron/$PROJECT.cron echo 'cron path:'$file; if test -s $file; then echo "cron文件内容不为空"; else echo "* * * * * sh /root/monitor.sh $PORT $PROJECT $MOD $JOB" >> ~/cron/$PROJECT.cron crontab ~/cron/$PROJECT.cron 复制代码
解析:中间echo的cron path路径,会输出到Jenkins日志里。目的是将执行 monitor.sh
写入服务器定时任务。cron规则就不介绍了,自定义即可。
说明:监控脚本的执行过程,应该加上日志输出(示例比较简单,勿模仿),这是好习惯,以便做记录!
关键代码:
#!/bin/sh PID=`/usr/sbin/lsof -i:$1 | grep -E 'java|node' | awk '{print $2}'` PROJECT=$2 MOD=$3 JOB=$4 mkdir -p ~/log touch ~/log/$PROJECT.log if test -z "$PID" then echo '后台自启动' >> ~/log/$PROJECT.log nohup /usr/bin/java -jar -Dsun.jnu.encoding=UTF8 -Dfile.encoding=UTF8 -Dspring.profiles.active=test,swagger$MOD ~/$PROJECT/$JOB.jar >> /dev/null 2>&1 & sleep 5 echo '启动成功!!!' >> ~/log/$PROJECT.log else echo 'service has been started' >> ~/log/$PROJECT.log fi 复制代码
解析:Jar包会运行于服务器的一个端口上,与其同时也会对应一个进程号,以一定的时间规则去检查进程号是否存在,判断不在自启动即可,逻辑很简单。
背景:进程被kill,若是企业开发人员想要知道被kill的原因,便会查看日志,而通知就很有必要了。由于所在企业使用钉钉工作,因此集成在钉钉机器人,可实时通知开发人员。
关键代码:
echo '钉钉通知开始' >> ~/log/$PROJECT.log curl 'https://oapi.dingtalk.com/robot/send?access_token= xxx ' / -H 'Content-Type: application/json' / -d ' {"msgtype": "text", "text": { "content": "钉钉--- jiayuan 监控测试,killed port:'$1',project:'$PROJECT' has been killed,已重启" } }' sleep 3 echo '钉钉通知结束' >> ~/log/$PROJECT.log 复制代码
说明: