package main import ( "context" "github.com/spf13/viper" "go.uber.org/zap" "golang.org/x/sync/errgroup" "os" "os/signal" "syscall" "time" ) func main() { // 初始化配置与日志 viper.AutomaticEnv() logger, _ := zap.NewProduction() defer logger.Sync() // 数据库初始化 db := initDB() defer db.Close() // HTTP 服务配置 server := initServer(viper.GetString("PORT"), logger) // 生命周期管理 ctx, cancel := context.WithCancel(context.Background()) g, gCtx := errgroup.WithContext(ctx) // 启动 HTTP 服务 g.Go(func() error { return server.Start() }) // 优雅关闭 g.Go(func() error { <-gCtx.Done() return server.Shutdown(30 * time.Second) }) // 信号监听 signals := make(chan os.Signal, 1) signal.Notify(signals, syscall.SIGINT, syscall.SIGTERM) g.Go(func() error { select { case <-gCtx.Done(): return gCtx.Err() case sig := <-signals: logger.Info("Received signal", zap.String("signal", sig.String())) cancel() // 触发关闭 } return nil }) if err := g.Wait(); err != nil { logger.Fatal("Server exited with error", zap.Error(err)) } }