package httpserver import ( "context" "fmt" "log/slog" "net/http" "os" "os/signal" "strings" "time" ) import ( "github.com/gin-gonic/gin" "github.com/spf13/cobra" "github.com/spf13/viper" ) import ( "resource-server/common" "resource-server/logger" "resource-server/models" "resource-server/router" _ "resource-server/service" ) var ( configFolder string port int mode string StartCmd = &cobra.Command{ Use: "run", Short: "Start API server", Example: "resource-server run -c config/config.toml", SilenceUsage: true, PreRun: func(cmd *cobra.Command, args []string) { setup() }, RunE: func(cmd *cobra.Command, args []string) error { return run() }, } ) func init() { StartCmd.Flags().StringVarP(&configFolder, "config", "c", "config/", "Start server with provided configuration folder") StartCmd.Flags().IntVarP(&port, "port", "p", 8000, "Tcp port server listening on") StartCmd.Flags().StringVarP(&mode, "mode", "m", "debug", "server mode ; eg:debug,test,release") viper.BindPFlag("port", StartCmd.Flags().Lookup("port")) viper.BindPFlag("mode", StartCmd.Flags().Lookup("mode")) } func setup() { if strings.HasSuffix(configFolder, "/") { configFolder = configFolder[:len(configFolder)-1] if strings.HasSuffix(configFolder, "/") { panic("invalid config folder") } } configToml := configFolder + "/config.toml" //1. 读取配置 common.SetupConfig(configToml) //2. 设置日志 logger.SetupLogger(true) //3. 初始化gorm models.SetupGorm(true) slog.Info(`starting api server`, "pid", os.Getpid()) } func run() error { gin.SetMode(common.ApplicationConfig.Mode) r := router.InitRouter() srv := &http.Server{ Addr: common.ApplicationConfig.Addr(), Handler: r, } go func() { // 服务连接 if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed { slog.Error("listen: ", err) panic("http server closed") } }() slog.Info("module: " + common.Module) slog.Info("desc: " + common.Desc) slog.Info("version: " + common.Version) slog.Info("build: " + common.Build) slog.Info(fmt.Sprintf("Server run at: %s", common.Now())) slog.Info(fmt.Sprintf("- Network: http://%s:%d/ \n", common.ApplicationConfig.Host, common.ApplicationConfig.Port)) slog.Info("Enter Control + C Shutdown Server \n") // 等待中断信号以优雅地关闭服务器(设置 5 秒的超时时间) quit := make(chan os.Signal) signal.Notify(quit, os.Interrupt) <-quit fmt.Printf("%s Shutdown Server ... \n", common.Now()) ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() if err := srv.Shutdown(ctx); err != nil { slog.Error("Server Shutdown:", "err", err) } slog.Info("Server exiting") logger.ShutdownLogger() return nil }