package main import ( "context" "flag" "fmt" "github.com/cloudflare/tableflip" "github.com/gin-gonic/gin" "github.com/robfig/cron/v3" "log" "net/http" "os" "os/signal" "runtime" "syscall" "time" "zhiyuan/pkg/config" "zhiyuan/pkg/db" "zhiyuan/pkg/logger" "zhiyuan/pkg/redis" "zhiyuan/pkg/sms" "zhiyuan/pkg/validate" "zhiyuan/routers" ) func init() { config.Setup() logger.Setup() db.Setup() redis.Setup() validate.Setup() sms.Setup() } func main() { c := cron.New(cron.WithSeconds()) c.AddFunc("0 0 0 * * *", func() { //logger.Sugar.Infof("Run cron") //worksitecheck.CheckCron() }) c.Start() gin.SetMode(config.Cfg.Server.RunMode) r := routers.InitRouters() readTimeout := config.Cfg.Server.ReadTimeout writeTimeout := config.Cfg.Server.WriteTimeout endPoint := fmt.Sprintf(":%d", config.Cfg.Server.HttpPort) maxHeaderBytes := 1 << 20 server := &http.Server{ Addr: endPoint, Handler: r, ReadTimeout: readTimeout, WriteTimeout: writeTimeout, MaxHeaderBytes: maxHeaderBytes, } var ( listenAddr = flag.String("listen", "localhost"+endPoint, "`Address` to listen on") pidFile = flag.String("pid-file", config.Cfg.Server.PidFile, "`Path` to pid file") ) flag.Parse() log.SetPrefix(fmt.Sprintf("%d ", os.Getpid())) // 1. 判断当前是否为 Windows 平台 if runtime.GOOS == "windows" { startServer(r, endPoint) } else { upg, err := tableflip.New(tableflip.Options{ PIDFile: *pidFile, }) if err != nil { panic(err) } defer upg.Stop() // Do an upgrade on SIGHUP go func() { sig := make(chan os.Signal, 1) signal.Notify(sig, syscall.SIGHUP) for range sig { err := upg.Upgrade() if err != nil { log.Println("Upgrade failed:", err) } } }() // Listen must be called before Ready ln, err := upg.Listen("tcp", *listenAddr) if err != nil { log.Fatalln("Can't listen:", err) } go func() { err := server.Serve(ln) if err != http.ErrServerClosed { log.Println("HTTP server:", err) } }() log.Printf("ready listen %s", endPoint) if err := upg.Ready(); err != nil { panic(err) } //models.WorkSiteAddReturnVisit() <-upg.Exit() // Make sure to set a deadline on exiting the process // after upg.Exit() is closed. No new upgrades can be // performed if the parent doesn't exit. time.AfterFunc(30*time.Second, func() { log.Println("Graceful shutdown timed out") os.Exit(1) }) // Wait for connections to drain. server.Shutdown(context.Background()) } } // 标准启动方式(Windows 使用) func startServer(router *gin.Engine, addr string) { server := &http.Server{ Addr: addr, Handler: router, } log.Printf("✅ 服务已启动,监听地址 %s\n", addr) log.Printf("👉 测试命令: curl http://localhost%s\n", addr) if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed { log.Fatalf("❌ 服务启动失败: %v\n", err) } }