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

2 篇文章 0 订阅
 最近想实现一个自己的文件服务器,但是频繁的修改代码,重启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参数( 2aa 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文件名

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值