You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
|
|
|
|
package gfsd
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"context"
|
|
|
|
|
"fmt"
|
|
|
|
|
"net/http"
|
|
|
|
|
"os"
|
|
|
|
|
"os/signal"
|
|
|
|
|
|
|
|
|
|
"syscall"
|
|
|
|
|
"time"
|
|
|
|
|
|
|
|
|
|
"github.com/gin-gonic/gin"
|
|
|
|
|
"github.com/spf13/viper"
|
|
|
|
|
"go.uber.org/zap"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
func Graceful_Shutdown(r *gin.Engine) {
|
|
|
|
|
|
|
|
|
|
srv := &http.Server{
|
|
|
|
|
Addr: fmt.Sprintf(":%d", viper.GetInt("app.port")),
|
|
|
|
|
Handler: r,
|
|
|
|
|
}
|
|
|
|
|
go func() {
|
|
|
|
|
// 开启一个goroutine启动服务
|
|
|
|
|
if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
|
|
|
|
|
zap.L().Fatal("listen: %s\n", zap.Error(err))
|
|
|
|
|
}
|
|
|
|
|
}()
|
|
|
|
|
|
|
|
|
|
// 等待中断信号来优雅地关闭服务器,为关闭服务器操作设置一个5秒的超时
|
|
|
|
|
quit := make(chan os.Signal, 1) // 创建一个接收信号的通道
|
|
|
|
|
// kill 默认会发送 syscall.SIGTERM 信号
|
|
|
|
|
// kill -2 发送 syscall.SIGINT 信号,我们常用的Ctrl+C就是触发系统SIGINT信号
|
|
|
|
|
// kill -9 发送 syscall.SIGKILL 信号,但是不能被捕获,所以不需要添加它
|
|
|
|
|
// signal.Notify把收到的 syscall.SIGINT或syscall.SIGTERM 信号转发给quit
|
|
|
|
|
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM) // 此处不会阻塞
|
|
|
|
|
<-quit // 阻塞在此,当接收到上述两种信号时才会往下执行
|
|
|
|
|
zap.L().Info("Shutdown Server ...")
|
|
|
|
|
// 创建一个5秒超时的context
|
|
|
|
|
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
|
|
|
|
defer cancel()
|
|
|
|
|
// 5秒内优雅关闭服务(将未处理完的请求处理完再关闭服务),超过5秒就超时退出
|
|
|
|
|
if err := srv.Shutdown(ctx); err != nil {
|
|
|
|
|
zap.L().Fatal("Server Shutdown", zap.Error(err))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
zap.L().Info("Server exiting")
|
|
|
|
|
}
|