package server import ( "context" "fmt" "io/ioutil" "net/http" "os" "os/signal" "syscall" "time" "videoweb/pub/common/laosiji" "videoweb/pub/common/log" "videoweb/pub/common/srvversion" "videoweb/pub/esmanager" "videoweb/pub/models" "videoweb/pub/mongos" "videoweb/pub/payCenter" "videoweb/pub/redis" "videoweb/pub/seo/googleindex" "videoweb/pub/storage/proxy" "videoweb/web/router" "videoweb/web/service" "videoweb/web/webg" "gopkg.in/yaml.v2" ) func init() { time.Local, _ = time.LoadLocation("Asia/Shanghai") } func Run(args []string) { showVersion() if err := initConfig(); err != nil { log.Error("init config err", log.E(err)) os.Exit(1) return } shopDb := mongos.NewManager(webg.Conf.Mongodb.Addr) if err := shopDb.Init(); err != nil { log.Error("connect shopDb err", log.E(err)) os.Exit(1) } mongos.Shop = shopDb shopLog := mongos.NewManager(webg.Conf.Mongodb.LogAddr) if err := shopLog.Init(); err != nil { log.Error("connect shopLog err", log.E(err)) os.Exit(1) } mongos.ShopLog = shopLog if err := redis.Init(redis.Options{ Addr: webg.Conf.Redis.Addr, Psw: webg.Conf.Redis.Passwd, Db: webg.Conf.Redis.Db, }); err != nil { log.Error("redis connect err", log.E(err)) os.Exit(1) } if err := initCollections(); err != nil { os.Exit(1) return } if err := initElasticSearch(); err != nil { log.Error("init ES failed", log.E(err)) os.Exit(1) } //初始化tg机器人 if webg.Conf.TgToken != "" { //tgbot.InitTgBot(webg.Conf.TgToken, "[汁乎Web]") } proxy.InitBucketVideoAddress(webg.Conf.BucketVideoAddressV2) initLaosiji() mongos.StartLid() initData() initSeoPush() initHttpServer() shutdownHandler() } func showVersion() { log.Info(fmt.Sprintf("sevice version:%s", srvversion.SERVICE_VERSION)) log.Info(fmt.Sprintf("git version:%s", srvversion.GIT_VERSION)) log.Info(fmt.Sprintf("build date:%s", srvversion.BUILD_DATE)) log.Info(fmt.Sprintf("build ip:%s", srvversion.BUILD_IP)) } func initConfig() error { buf, err := ioutil.ReadFile("conf/web.yaml") if err != nil { return err } if err = yaml.Unmarshal(buf, &webg.Conf); err != nil { return err } payCenter.Init(webg.Conf.NewPayCenter) return nil } // mongo表 func initCollections() error { return nil } // 数据 func initData() { models.Init() service.Start() } // 搜索引擎推送 func initSeoPush() { if webg.Conf.RunMod != "prod" { return } googleindex.Init(context.Background()) } func initElasticSearch() error { es, err := esmanager.NewManager(webg.Conf.Es.Addr, webg.Conf.Es.User, webg.Conf.Es.Pass) if err != nil { log.Info("new es failed", log.Any("err", err)) return err } if err = es.ClientConnect(); err != nil { log.Info("connect es failed", log.Any("err", err)) return err } esmanager.Instance = es log.Info("es:Init Ok!") return nil } func initHttpServer() { addr := fmt.Sprintf(":%s", webg.Conf.ListenAddr) srv := &http.Server{ Addr: addr, Handler: router.Init(), } go func() { log.Info("服务已启动", log.Any("地址", addr)) if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed { log.Fatal("listen:", log.E(err)) } }() } func shutdownHandler() { quit := make(chan os.Signal) signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM, os.Kill) <-quit log.Warn("Shutdown... server") service.Stop() done := make(chan struct{}) go func() { mongos.Shop.DisConnect() mongos.ShopLog.DisConnect() redis.Disconnect() // srv_resource.ClosePrefetch() done <- struct{}{} }() select { case <-time.After(5 * time.Second): log.Warn("shutdown timeout....") case <-done: log.Info("graceful shutdown") } } func initLaosiji() { if webg.Conf.LsjMediaConf.ApiUrl == "" { return } cli := laosiji.New(webg.Conf.LsjMediaConf.ApiUrl, webg.Conf.LsjMediaConf.AppId, webg.Conf.LsjMediaConf.ApiKey) d := laosiji.NewDomains(cli) laosiji.LaosijiClient = cli laosiji.LaosijiDomains = d hr := webg.Conf.LsjMediaConf.DomainsRefreshHr if hr <= 0 { hr = 3 } d.StartAutoRefresh(time.Duration(hr) * time.Hour) go func() { ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) defer cancel() if _, err := d.Refresh(ctx); err != nil { log.Error("Init Laosiji domains 首次拉取失败(后台重试,不影响启动)", log.E(err)) } else { log.Info("Init Laosiji OK...") } }() }