package server import ( "fmt" "net/http" "os" "os/signal" "stat/common/enum/consts" "stat/common/genId" "stat/common/log" "stat/common/mongos" "stat/common/redis" "stat/models" "stat/router" "stat/service/botser" "stat/service/cacheSer" "stat/service/consumer" "stat/service/domainser" "stat/service/versionSer" "stat/skd" "stat/statg" "syscall" "time" "github.com/dchest/captcha" ) func init() { time.Local, _ = time.LoadLocation("Asia/Shanghai") } func Run(args []string) { // 初始化配置文件 if err := initConfig(); err != nil { os.Exit(1) return } // 初始化数据库 if err := initMongoDB(); err != nil { os.Exit(1) return } // 初始化redis if err := initRedis(); err != nil { os.Exit(1) return } // 图片验证器 statg.VerifyIMGStore = captcha.NewMemoryStore(captcha.CollectNum, captcha.Expiration) // 自增id genId.Start() // 初始化缓存 cacheSer.Init() // 测试模式不启用定时任务及同步 if statg.Conf.RunMod == consts.RunModRelease || statg.Conf.RunMod == consts.RunModeDev { // 机器人初始化 statg.InitBot() // 启动机器人 botser.StartBot() } if statg.Conf.RunMod == consts.RunModRelease { // LandPage versionSer.Init() // Domain Check domainser.Start() // 定时任务 skd.Start() // APP同步数据 go consumer.SyncInit() } // web服务器 initHttpServer() // 资源释放 waitQuit() } func initConfig() error { return statg.LoadConfig("conf/server.json") } func initMongoDB() error { mgoDB := mongos.NewManager(statg.Conf.Mongo.Url) if err := mgoDB.Connect(); err != nil { log.Error("mgoDB connect err", log.E(err)) return err } mongos.MgoManager = mgoDB // 初始化数据库索引 models.InitIndex() return nil } func initRedis() error { rds, err := redis.NewManagerWithUrl(statg.Conf.Redis.Url, nil) if err != nil { log.Error("rds init err", log.E(err)) return err } redis.StatRds = rds return nil } func initHttpServer() { addr := fmt.Sprintf(":%d", statg.Conf.Port) srv := &http.Server{ Addr: addr, ReadTimeout: 30 * time.Second, WriteTimeout: 90 * time.Second, IdleTimeout: 120 * time.Second, Handler: router.SetupGin(), } go func() { log.Info("服务已启动", log.Any("地址", addr), log.Any("模式", statg.Conf.RunMod)) if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed { log.Fatal("listen:", log.E(err)) } }() } func waitQuit() { quit := make(chan os.Signal) signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM) <-quit log.Warn("Shutdown... server") botser.SaveServerNormalCloseFlag() done := make(chan int) go Shutdown(done) select { case <-time.After(5 * time.Second): log.Warn("shutdown timeout....") case <-done: log.Info("graceful shutdown") } } func Shutdown(done chan int) { cacheSer.SyncWriters() if mongos.MgoManager != nil { mongos.MgoManager.DisConnect() } if redis.StatRds != nil { redis.StatRds.Close() } close(done) }