红联Linux门户
Linux帮助

Bash脚本实现实时监控和自动重启golang服务器

发布时间:2017-05-01 11:12:13来源:linux网站作者:lovixs
最近想实现一个自己的文件服务器,但是频繁的修改代码,重启go服务器(实际上目前就是几个.go文件)实在是让人痛苦,于是想到肯定有实现类似beego和rails这些框架实时监控代码改动并重启服务器的方法。于是我就想自己实现一个试试。
 
首先我认为思路应该是很清晰的,第一要监控起需要监控的文件,要能知道文件什么时候发生改动了,第二就是在文件发生变动的时候做出动作,简单来说就是杀死服务器的进程,然后平滑重启这个进程。
 
一开始我是想自己用go来实现,但无奈找不到合适的资料加上自己技艺学浅,后来还是要找google daddy,果然简单一查就有至少三个框架已经实现了这些功能。以下便是几个框架的地址(ps:虽然我没有自己的实现(pps:以后会有的),但是上一段思路是没问题的,因为用bash 脚本的方式就是这么实现的):
fresh框架:
https://github.com/pilu/fresh
gin框架(这个我没装上,希望读者可以幸运的装好吧)
https://github.com/codegangsta/gin
go-reload:
https://github.com/alexedwards/go-reload
 
我选择了第三种方式,即go-reload方法。原因有两个一是目前它完全满足我的需求,二就是它真的很简单,加上注释也只有80行代码。而且操作也是很容易。只需把代码粘贴到一个名为go-reload文件中,chmod +x变为可执行文件,然后移动到/usr/local/bin,使用go-reload ××.go就完成了,所以到这里我不得不感叹一句bash的神奇(原谅我的无知,学了三年计算机才领略到bash的神奇)。
 
第一种方式是使用golang实现的,当然也是很好的,这个我们以后再细细的分析。(使用方式Usage里边说的十分清楚,而且亲测可行,很好用)
重点说说第二种方式,使用方法刚才已经说了,项目地址下边也有介绍。
 
实现的代码如下:
go-reload文件
#!/bin/bash
#monitor the with inotify-tools
function monitor() {
if [ "$2" = "true" ];  then
# Watch all files in the specified directory
# Call the restart function when they are saved
inotifywait -q -m -r -e close_write -e moved_to $1 |
while read line; do
restart
done
else
# Watch all *.go files in the specified directory
# Call the restart function when they are saved
inotifywait -q -m -r -e close_write -e moved_to --exclude '[^g][^o]$' $1 |
while read line; do
restart
done
fi
}
# Terminate and rerun the main Go program
function restart {
if [ "$(pidof $PROCESS_NAME)" ]; then
killall -q -w -9 $PROCESS_NAME
fi
echo ">> Reloading..."
eval "go run $ARGS &"
}
# Make sure all background processes get terminated
function close {
killall -q -w -9 inotifywait
exit 0
}
trap close INT
echo "== Go-reload"
WATCH_ALL=false
#check if the command has "-a" option
while getopts ":a" opt; do
case $opt in
a)
WATCH_ALL=true
;;
\?)
echo "Invalid option: -$OPTARG" >&2
exit 0
;;
esac
done
shift "$((OPTIND - 1))"
#get the process name 
FILE_NAME=$(basename $1)
PROCESS_NAME=${FILE_NAME%%.*}
#get the main go file
ARGS=$@
# Start the main Go program
echo ">> Watching directories, CTRL+C to stop"
eval "go run $ARGS &"
# Monitor all /src directories on the GOPATH
OIFS="$IFS"
IFS=':'
for path in $GOPATH
do
monitor $path/src $WATCH_ALL &
done
IFS="$OIFS"
# If the current working directory isn't on the GOPATH, monitor it too
if [[ $PWD != "$GOPATH/"* ]]
then
monitor $PWD $WATCH_ALL
fi
wait
 
首先说明脚本并没有自己实现检测文件变化功能,而是用了inotify-tools实现的这个功能,只需要运行sudo apt-get install inotify-tools命令就可以安装。然后bash脚本很通俗易懂只要在几个关键的地方输出几个变量,及时我不会他的语法也可以明白是怎么回事。
 
然后说一说我认为比较重要的几个点。主要函数就两个,一个“monitor()”函数,一个“restart”函数,也就是实现的以上提到的思路的两点,检测和重启。
monitor函数利用inotify实现文件监控,首先判断是否含-a参数(2为−a参数的标志),然后−a就监控所有文件(GOPATH路径下所有文件),否则就只监控Go文件。无论是那种情况发生了变化,最终都要调用restart函数来实现服务器的重启。
restart函数实现进程重启功能。killall -q -w -9杀死当前运行的进程,然后运行go run把命令重新执行。这样重启就完成了。
 
最后值得说一下进程的名字一般就是你go文件名字去掉.go,例如我运行go run myserver.go,那么一般进程名字就是myserver了。文件中FILE_NAME=$(basename $1)
PROCESS_NAME=${FILE_NAME%%.*}就是通过文件名来推出进程名。
最后的最后,写的不对的欢迎指正,欢迎交流。
 
之前在把脚本编程可执行文件那里写错了,非常抱歉。整个的流程应该是这样的:
1,新建一个go-reload文件,添加以上代码。
2,同目录下执行命令chmod +x go-reload ,将go-reload变为可执行的bash脚本。
3,把脚本移动到/usr/local/bin目录下:同目录下执行mv go-reload /usr/local/bin
4,进入我们需要自动监控的文件的文件加执行 go-reload go文件名
 
本文永久更新地址:http://www.linuxdiyf.com/linux/30415.html