大概流程

当超过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