package boot import ( "context" "fmt" redisLib "github.com/go-redis/redis/v8" "github.com/gogf/gf/frame/g" "github.com/gogf/gf/net/ghttp" "github.com/gogf/gf/os/gcron" "go.uber.org/dig" "gorm.io/gorm" agent2 "gxt-file-server/app/agent" "gxt-file-server/app/bll" "gxt-file-server/app/bll/impl" "gxt-file-server/app/model" "gxt-file-server/pkg/gplus" "gxt-file-server/pkg/logger" "gxt-file-server/pkg/middleware" "gxt-file-server/pkg/redis" "gxt-file-server/pkg/store" "gxt-file-server/pkg/utils" "gxt-file-server/router" "log" "os" ) // VERSION 定义应用版本号 const VERSION = "1.0.0" func init() { // 初始化logger logger.Init(g.Cfg().GetString("common.run_mode")) logger.SetVersion(VERSION) logger.SetTraceIdFunc(utils.NewTraceID) ctx := logger.NewTraceIDContext(context.Background(), utils.NewTraceID()) Init(ctx) } // Init 初始化App, func Init(ctx context.Context) func() { logger.Printf(ctx, "服务启动,运行模式:%s,版本号:%s,进程号:%d", g.Cfg().Get("common.run_mode"), VERSION, os.Getpid()) // 初始化依赖注入容器 container, call := buildContainer(ctx) // 初始化路由注册 s := g.Server() // 每个请求生成新的追踪Id,如果上下文件中没有trace-id s.Use(middleware.TraceIdMiddleware()) // file middleware filePrefix := fmt.Sprintf("/%s/", g.Cfg().GetString("agent.DefaultFilePathPrefix")) s.Use(middleware.FileMiddleWare(middleware.AllowPathPrefixNoSkipper(filePrefix))) // 统一处理内部错误 s.Use(func(r *ghttp.Request) { r.Middleware.Next() if err := r.GetError(); err != nil { gplus.ResError(r, err) } }) initCron(ctx, container) router.InitRouters(s, container) return func() { if call != nil { call() } } } // 初始化redis func initRedis(ctx context.Context, container *dig.Container) func() { addr := g.Cfg().GetString("redis.addr") password := g.Cfg().GetString("redis.password") db := g.Cfg().GetInt("redis.db") redisCli := redis.Init(ctx, addr, password, db) redisCli.ConfigSet(ctx, "set notify-keyspace-events", "Ex") logger.Printf(ctx, "REDIS初始化成功,当前服务器[%s, %d]", addr, db) // 注入redis client _ = container.Provide(func() *redisLib.Client { return redisCli }) return func() { _ = redisCli.Close() } } func initAgent(ctx context.Context, container *dig.Container) func() { _ = container.Invoke(func(rCli *redisLib.Client, fhm model.IFileHistory) { addr := g.Cfg().GetString("minio.addr") aKey := g.Cfg().GetString("minio.assess_key") sKey := g.Cfg().GetString("minio.secret_key") m := store.MiniStoreInit(addr, aKey, sKey) agent2.DefaultAgent().SetBackend(m) agent2.DefaultAgent().SetConfig(&agent2.Config{ DefaultExpireTime: g.Cfg().GetInt("agent.DefaultExpireTime"), }) agent2.DefaultAgent().SetRedisClient(rCli) agent2.DefaultAgent().SetFileHistoryModel(fhm) _ = agent2.DefaultAgent().Start(ctx) }) return func() { } } // 初始化存储,目前只初始化gorm func initStore(ctx context.Context, container *dig.Container) (func(), error) { var storeCall func() db, err := initGorm() if err != nil { return storeCall, err } // 如果自动映射数据表 if g.Cfg().GetBool("gorm.enable_auto_migrate") { err = autoMigrate(db) if err != nil { return storeCall, err } } // 注入DB _ = container.Provide(func() *gorm.DB { return db }) // 注入model接口 _ = InjectModel(container) storeCall = func() { sqlDb, _ := db.DB() _ = sqlDb.Close() } logger.Printf(ctx, "MYSQL初始化成功, 服务器[%s], 数据库[%s]", g.Cfg().GetString("mysql.host"), g.Cfg().GetString("mysql.db_name")) return storeCall, nil } // 构建依赖注入容器 func buildContainer(ctx context.Context) (*dig.Container, func()) { container := dig.New() // 初始化存储模块 storeCall, err := initStore(ctx, container) if err != nil { panic(err) } // 初始化redis模块 var redisCall func() if g.Cfg().GetBool("redis.enable") { redisCall = initRedis(ctx, container) } agentCall := initAgent(ctx, container) // 注入bll impl.Inject(container) return container, func() { if storeCall != nil { storeCall() } if redisCall != nil { redisCall() } if agentCall != nil { agentCall() } } } func initCron(ctx context.Context, container *dig.Container) { //秒 分 时 日 月 周 runMode := g.Cfg().GetString("common.run_mode") _ = container.Invoke(func( chunk bll.IFileChunk, ) { switch runMode { case "debug", "test": initCronDebug(ctx, chunk) //定时清理过期文件块 case "release": initCronRelease(ctx, chunk) //定时清理过期文件块 } logger.Printf(ctx, "gCorn初始化成功\n") }) } func initCronDebug(ctx context.Context, chunk bll.IFileChunk) { _, err := gcron.Add("0 5 * * * *", func() { err := chunk.ClearChunks(ctx) if err != nil { log.Fatalln(err) return } }) if err != nil { logger.Errorf(ctx, err.Error()) } } func initCronRelease(ctx context.Context, chunk bll.IFileChunk) { clearChunk := g.Cfg().GetString("corn.clear_chunk") _, err := gcron.Add(clearChunk, func() { err := chunk.ClearChunks(ctx) if err != nil { log.Fatalln(err) return } }) if err != nil { logger.Errorf(ctx, err.Error()) } }