package main import ( "context" "dashboard/dao/sqldb" "dashboard/logger" "dashboard/routes" "dashboard/settings" "errors" "flag" "fmt" "net/http" "os" "os/signal" "syscall" "time" "go.uber.org/zap" ) var config = flag.String("f", "./config/config.yaml", "config file path") func main() { flag.Parse() sets := settings.New(settings.WithName(*config)) log, err := logger.New( logger.WithFileName(sets.LogConfig.Filename), logger.WithLevel(sets.LogConfig.Level), logger.WithMaxAge(sets.LogConfig.MaxAge), logger.WithMaxSize(sets.LogConfig.MaxSize), logger.WithMaxBackUp(sets.LogConfig.MaxBackUps), logger.WithMode(sets.BaseConfig.Mode), ) if err != nil { fmt.Println(err) panic(err) } defer func() { _ = log.Sync() }() log.Info("Settings and log init ok") db, err := sqldb.NewDb(sets.SqlConfig) if err != nil { log.Sugar().Panicf("New db error: %v", err) } sqldb.SqlDbInit(log, db) if err != nil { log.Sugar().Panicf("New db error: %v", err) } r := routes.Setup(log, *sets.RateLimitConfig, *sets.JwtConfig) listenAndServe(fmt.Sprintf(":%d", sets.BaseConfig.Port), r, log) } func listenAndServe(addr string, handle http.Handler, log *logger.Logger) { srv := &http.Server{ Addr: addr, Handler: handle, } log.Sugar().Infof("Server listen on %s", addr) go func() { // 开启一个goroutine启动服务 if err := srv.ListenAndServe(); err != nil && !errors.Is(err, http.ErrServerClosed) { log.Error("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 // 阻塞在此,当接收到上述两种信号时才会往下执行 log.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 { log.Error("Server Shutdown: ", zap.Error(err)) } log.Info("Server exiting") }