Files
2026-05-20 16:13:58 +08:00

152 lines
2.9 KiB
Go

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)
}