package main import ( "91porn-server/common/cachev2" "91porn-server/common/dataReport" "91porn-server/common/services" "context" "fmt" "net/http" "os" "os/signal" "syscall" "time" "91porn-server/app/api/updownctrl" "91porn-server/app/appg" "91porn-server/app/router" "91porn-server/app/service/activityclient" "91porn-server/app/service/imser" "91porn-server/common" "91porn-server/common/conf" "91porn-server/common/constant" _ "91porn-server/common/daichong" "91porn-server/common/db" "91porn-server/common/email" "91porn-server/common/filter" "91porn-server/common/httputil" "91porn-server/common/laosiji_app" "91porn-server/common/log" recommendqueue "91porn-server/common/shortrecommend" "91porn-server/common/sms" "91porn-server/common/tg" "91porn-server/models" "91porn-server/models/Init" _ "91porn-server/models/commod" _ "91porn-server/models/v/moduleconfmod" // swagger依赖 _ "91porn-server/models/v/productmod" _ "91porn-server/models/v/rchgamtmod" // swagger依赖 _ "91porn-server/models/v/recommod" // swagger依赖 _ "91porn-server/models/v/sourcemod" _ "91porn-server/models/v/systemmod" _ "91porn-server/models/v/txnmod" // swagger _ "91porn-server/models/v/usermod" // swagger依赖 _ "91porn-server/models/v/versionmod" _ "91porn-server/models/v/videocoupon" // swagger依赖 _ "91porn-server/models/v/vidmod" // swagger _ "91porn-server/models/v/walletmod" swaggerFiles "github.com/swaggo/files" ginSwagger "github.com/swaggo/gin-swagger" ) var httpServer *http.Server // @title app文档 // @version 1.0 // @description 短视频服务后端API接口文档 // @contact.name API Support // @contact.url http://www.swagger.io/support // @license.name Apache 2.0 // @license.url http://www.apache.org/licenses/LICENSE-2.0.html func init() { cfg := appg.GlobalConfig{} if err := conf.LoadJSON("config/app.json", &cfg); err != nil { fmt.Printf("startUp get config error: %v\n", err) os.Exit(1) } fmt.Println("use local config successfully") //加载配置 appg.Conf = &cfg log.Init(log.Options{Level: appg.Conf.Log.Level, DisableStack: appg.Conf.Log.DisableStacktrace}) sms.Init(appg.Conf.SMS) laosiji_app.Init(appg.Conf.LaoSiJiAiMate) common.InitGinSecret(appg.Conf.Base.ResKey, appg.Conf.Base.ResKey360, appg.Conf.Base.Env) if cfg.Base.Env == constant.ProdEnv { appg.Bot = tg.New(tg.TianTian_Bot, fmt.Sprintf("短视频[env:%s]", appg.Conf.Base.Env)) common.SetPanicHandler(func(s string) { _ = appg.Bot.Send(tg.Msg{ChatId: tg.ChatIdServerTeam, Text: "[App-Server]" + s}) }) } } // @host 127.0.0.1:9009 // @BasePath func main() { time.Local, _ = time.LoadLocation("Asia/Shanghai") common.Go(startUp) waitQuit() } func startUp() { //初始化数据库 ds := db.InitDS(appg.InitMongodbParam(models.RegisterPool)) if len(ds) > 0 { for k, v := range ds { switch k { case models.VideoDb: appg.VideoDB = v case models.LogDb: appg.LogDB = v case models.StatDb: appg.StatDB = v } } } appg.ProxyCfg = &httputil.ProxyCfg{ Host: appg.Conf.URL.HttpProxy, IsActive: false, } dataReport.Init(dataReport.Config{ ApiUrl: appg.Conf.DataReport.Url, }) //初始化静态配置 appg.InitStatic() // 初始化Redis appg.InitRedis() if err := recommendqueue.SetKeyTTLHours(appg.Conf.ShortRecommendKeyTTL()); err != nil { log.Error("short recommend key TTL config invalid, use default", log.E(err), log.Any("configuredHours", appg.Conf.ShortRecommendKeyTTL())) _ = recommendqueue.SetKeyTTLHours(72) } services.Init(appg.Redis) // 初始化缓存操作中间件 cachev2.Init(appg.Redis, log.ZapLog) // 初始化ElasticSearch appg.InitElastic() Init.InitMongo() Init.ESInit() Init.InitCache() // init email service _ = email.MustInit(context.TODO(), appg.Conf.AWS.SES) // 初始化文本过滤器 filter.Start() // 启动时异步取一次 IM appToken + 每小时刷新(不阻断启动) imser.InitAppToken() // 启动活动服定时同步 activityclient.Start() //开始http ginRouter := router.SetupGin() ginRouter.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler)) port := appg.Conf.Base.Port httpServer = &http.Server{ Addr: fmt.Sprintf(":%d", port), Handler: ginRouter, } log.Info("Start Listen ...", log.Any("port", port)) if err := httpServer.ListenAndServe(); err != nil && err != http.ErrServerClosed { log.Fatal("server listen err", log.E(err)) } // Block Here log.Info("httpServer quit...") } func waitQuit() { //graceful exit ch := make(chan os.Signal, 1) signal.Notify(ch, syscall.SIGTERM, syscall.SIGQUIT, syscall.SIGINT) <-ch log.Info("Recv Signal, Shutdown Server Start...") ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() if httpServer != nil { if err := httpServer.Shutdown(ctx); err != nil { log.Error("Server Shutdown error", log.E(err)) } } db.CloseDS() updownctrl.FlushM3u8RefererStats() // 退出前把进程内聚合的来源计数刷回 Redis,减少丢失 if err := appg.RedisClose(); err != nil { log.Error("redis close error", log.E(err)) return } log.Warn("Shutdown Server OK...") }