大概流程
当超过2s(自定义设置)则强行终止
直接上代码
func main(){
// ------------------------- 平滑重启 -----------------------
g := router.Load() // 这里的g 代表 *gin.Engine
s := &http.Server{
Addr: ":" + viper.GetString("gin.port"),
Handler: g,
ReadTimeout: 10 * time.Second,
//WriteTimeout: 10 * time.Second,
//MaxHeaderBytes: 1 << 20
}
go func() {
// service connections
if err := s.ListenAndServe(); err != nil && err != http.ErrServerClosed {
//log.Fatalf(err, "listen: %s\n", err)
log.Fatal(err)
}
}()
listenSignal(s) // two 处理优雅重启
}
func listenSignal(httpSrv *http.Server) {
sigs := make(chan os.Signal, 1)
signal.Notify(sigs, syscall.SIGHUP, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT)
select {
case sig := <-sigs:
log.Println("收到信号notify sigs", sig)
zlog.F().Info("收到信号notify sigs", sig)
ctx, cancel := context.WithTimeout(context.Background(), time.Second*2) // 2s没有处理完,则强制关闭
defer cancel()
err := httpSrv.Shutdown(ctx)
if err != nil {
log.Println(err)
zlog.F().Error(err)
}
log.Println("关闭,http shutdown")
zlog.F().Info("关闭,http shutdown")
}
}
附上脚本 admin.sh
#!/bin/sh
# chkconfig: 2345 87 88
# Description: huidu-go-ulive-app service
. /etc/init.d/functions
APP_HOME=/data/yekong_api
prog=yekong_api
start_scripts_name="yekong_api"
process="./yekong_api"
function startSer() {
chmod +x ${start_scripts_name}
cd ${APP_HOME} && nohup ./${start_scripts_name} > output.log 2>&1 &
if [ $? -eq 0 ];then
action "Starting $prog Server" /bin/true
else
action "Starting $prog Server" /bin/false
fi
}
function stopSer() {
PID=$(ps aux | grep -w ${process} | grep -v grep | awk '{print $2}')
if [ "${PID}" ];then
time=2
time_interval=0.5
TIME_NUM=$(echo "${time} ${time_interval}" | awk '{print $1 / $2}')
echo "次数 $TIME_NUM"
kill -2 ${PID}
i=0
while(( $i<=$TIME_NUM ))
do
PID=$(ps aux | grep -w ${process} | grep -v grep | awk '{print $2}')
if [ "$PID" ];then
[ $i == ${TIME_NUM} ] && kill -9 $PID || sleep ${time_interval}
echo "pid为: $PID"
else
echo "平滑退出,break"
break
fi
let "i++"
done
fi
[ $? -eq 0 ] && action "Stop $prog Server" /bin/true || action "Stop $prog Server" /bin/false
}
function status() {
PID=$(ps aux | grep -w ${process} | grep -v grep | awk '{print $2}')
if [ "$PID" ];then
if kill -0 $PID > /dev/null 2> /dev/null ; then
return 0
else
return 2 # program is dead but pid file exists
fi
else
return 3 # program is not running
fi
}
case "$1" in
start)
status
code=$?
if [ $code -eq 0 ]; then
echo "$prog server is already running"
else
startSer
code=$?
fi
exit $code
;;
stop)
stopSer
;;
restart)
stopSer
startSer
;;
status)
status
if [ $? -eq 0 ];then
echo -e "$prog server \033[32mRunning\033[0m (PID:$PID)..."
else
echo -e "$prog server \033[31m Not running\033[0m..."
fi
;;
*)
echo "Usage: service $prog {start|stop|restart|status}"
exit 1
esac
exit 0
启动 ./admin.sh start
停止 ./admin.sh stop
重启 ./admin.sh restart
状态 ./admin.sh status