From 1f4f63cf6e65688cc4449e06f5fbfc35bed30aae Mon Sep 17 00:00:00 2001 From: "Logan.Li" Date: Fri, 26 Jun 2026 13:23:30 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20mode=3Dlocal=20=E7=BB=9F=E4=B8=80?= =?UTF-8?q?=E8=B5=B0=20SQLite=20+=20redka=20=E6=9C=AC=E5=9C=B0=E5=AD=98?= =?UTF-8?q?=E5=82=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 二进制 --mode local 或环境变量 MODE=local 自动配置 SQLite + redka - K8s Deployment 默认 MODE=local,移除外部 MySQL/Redis 依赖 - /version 返回 redis_driver;SQLite 兼容 agent 数据清理 SQL --- backend/main.go | 76 ++++++++++++++++++++----------- deploy/kubernetes/configmap.yaml | 19 +++----- deploy/kubernetes/deployment.yaml | 35 ++++++++------ run.sh | 2 +- 4 files changed, 78 insertions(+), 54 deletions(-) diff --git a/backend/main.go b/backend/main.go index cb59104..3b0c8da 100644 --- a/backend/main.go +++ b/backend/main.go @@ -34,7 +34,7 @@ var ( var ( flagPort = flag.String("port", "", "服务端口 (默认: 8080)") flagConfig = flag.String("config", "", "配置文件路径 (默认: config.yaml)") - flagMode = flag.String("mode", "", "运行模式: development, production, release") + flagMode = flag.String("mode", "", "运行模式: local (SQLite+redka), development, production, release") flagLogLevel = flag.String("log-level", "", "日志级别: debug, info, warn, error") // 数据库参数 @@ -107,9 +107,12 @@ func main() { zap.String("port", cfg.Port), ) - // 设置Gin模式 - if cfg.Mode == "production" || cfg.Mode == "release" { + // 设置 Gin 模式(local 与 release 一样走 ReleaseMode)// Logan.Li + switch cfg.Mode { + case "production", "release", "local": gin.SetMode(gin.ReleaseMode) + default: + gin.SetMode(gin.DebugMode) } // 初始化数据库 @@ -154,25 +157,31 @@ func main() { // 版本信息 API r.GET("/version", func(c *gin.Context) { c.JSON(http.StatusOK, gin.H{ - "version": Version, - "build_time": BuildTime, - "git_commit": GitCommit, - "mode": cfg.Mode, - "db_driver": cfg.Database.Driver, + "version": Version, + "build_time": BuildTime, + "git_commit": GitCommit, + "mode": cfg.Mode, + "db_driver": cfg.Database.Driver, + "redis_driver": cfg.Redis.Driver, }) }) // 注册路由 router.Register(r, db, log, cfg, cache) - // 定期清理旧的 agent 上报数据(保留 7 天,防止表膨胀影响查询性能) + // 定期清理旧的 agent 上报数据(保留 7 天,防止表膨胀影响查询性能)// Logan.Li go func() { ticker := time.NewTicker(24 * time.Hour) defer ticker.Stop() for range ticker.C { - result := db.Exec("DELETE FROM monitor_agent_reports WHERE report_time < DATE_SUB(NOW(), INTERVAL 7 DAY)") - if result.RowsAffected > 0 { - log.Info("清理过期的 agent 上报数据", zap.Int64("rows", result.RowsAffected)) + var rows int64 + if cfg.Database.Driver == "sqlite" { + rows = db.Exec("DELETE FROM monitor_agent_reports WHERE report_time < datetime('now', '-7 days')").RowsAffected + } else { + rows = db.Exec("DELETE FROM monitor_agent_reports WHERE report_time < DATE_SUB(NOW(), INTERVAL 7 DAY)").RowsAffected + } + if rows > 0 { + log.Info("清理过期的 agent 上报数据", zap.Int64("rows", rows)) } } }() @@ -265,20 +274,8 @@ func loadConfig() *config.Config { // CLI flags 覆盖(最高优先级)// Logan.Li applyFlags() - // --mode local 快捷模式:自动配置 SQLite + redka 本地缓存 // Logan.Li - if *flagMode == "local" || viper.GetString("mode") == "local" { - // 数据库:SQLite,文件名 sqlite3.db - if *flagDBDriver == "" { - viper.Set("database.driver", "sqlite") - } - if *flagDBName == "" { - viper.Set("database.dbname", "data/sqlite3.db") - } - // 缓存:redka 本地内嵌(无需外部 Redis) - if *flagRedisDriver == "" { - viper.Set("redis.driver", "redka") - } - } + // mode=local:强制 SQLite + redka(CLI 显式传 --db-driver/--redis-driver 时可覆盖)// Logan.Li + applyLocalMode() // 解析配置 // Logan.Li var cfg config.Config @@ -290,6 +287,33 @@ func loadConfig() *config.Config { return &cfg } +// isFlagSet 判断 CLI 参数是否被显式传入 // Logan.Li +func isFlagSet(name string) bool { + found := false + flag.Visit(func(f *flag.Flag) { + if f.Name == name { + found = true + } + }) + return found +} + +// applyLocalMode local 模式:不依赖外部 MySQL/Redis,使用 SQLite + redka // Logan.Li +func applyLocalMode() { + if viper.GetString("mode") != "local" { + return + } + if !isFlagSet("db-driver") { + viper.Set("database.driver", "sqlite") + } + if !isFlagSet("db-name") { + viper.Set("database.dbname", "data/sqlite3.db") + } + if !isFlagSet("redis-driver") { + viper.Set("redis.driver", "redka") + } +} + // applyFlags 将 CLI 参数映射到 viper(覆盖 config.yaml 和默认值)// Logan.Li func applyFlags() { // 检查是否有任何 flag 被显式设置 // Logan.Li diff --git a/deploy/kubernetes/configmap.yaml b/deploy/kubernetes/configmap.yaml index b4195a9..f1fc72b 100644 --- a/deploy/kubernetes/configmap.yaml +++ b/deploy/kubernetes/configmap.yaml @@ -1,7 +1,7 @@ # config.yaml — 由 ConfigMap 挂载到 /app/config.yaml # 注意:环境变量优先级高于此文件 (viper AutomaticEnv) -# 部署时通过 Deployment env 设置 DATABASE_HOST / REDIS_HOST 等覆盖以下值 -# 此文件仅作为 fallback 默认值 +# 默认 MODE=local(Deployment env)→ SQLite + redka,无需外部 MySQL/Redis +# 集群模式:Deployment 设 MODE=release 并配置 DATABASE_/REDIS_ 环境变量 apiVersion: v1 kind: ConfigMap metadata: @@ -9,24 +9,19 @@ metadata: namespace: devops data: config.yaml: | - mode: release + mode: local port: "8080" log_level: info database: - driver: mysql - host: 10.10.10.75 - port: 3306 - user: root - password: aiops_root_2026 - dbname: aiops - charset: utf8mb4 + driver: sqlite + dbname: data/sqlite3.db max_conn: 100 max_idle: 10 redis: - driver: redis - host: 10.10.10.75 + driver: redka + host: localhost port: 6379 password: "" db: 0 diff --git a/deploy/kubernetes/deployment.yaml b/deploy/kubernetes/deployment.yaml index 29bdd57..387c3f8 100644 --- a/deploy/kubernetes/deployment.yaml +++ b/deploy/kubernetes/deployment.yaml @@ -43,26 +43,31 @@ spec: ports: - name: http containerPort: 8080 - # ── 运行时环境变量 (仅覆盖代码默认值, 其余走 viper 默认) ── + # ── 运行时环境变量 (环境变量 > config.yaml > 默认值) ── + # mode=local → SQLite + redka 本地存储,无需外部 MySQL/Redis // Logan.Li + # 切换集群模式时改为 mode=release 并取消注释下方 DATABASE_/REDIS_ 变量 env: - name: TZ value: Asia/Shanghai - - name: DATABASE_DRIVER - value: "mysql" - - name: DATABASE_HOST - value: "10.10.10.75" - - name: DATABASE_USER - value: "root" - - name: DATABASE_PASSWORD - value: "aiops_root_2026" - - name: DATABASE_DBNAME - value: "aiops" - - name: REDIS_DRIVER - value: "redis" - - name: REDIS_HOST - value: "10.10.10.75" + - name: MODE + value: local - name: JWT_SECRET value: "aiops-jwt-secret-key-2026" + # --- 集群模式(mode=release)时启用 --- + # - name: DATABASE_DRIVER + # value: "mysql" + # - name: DATABASE_HOST + # value: "10.10.10.75" + # - name: DATABASE_USER + # value: "root" + # - name: DATABASE_PASSWORD + # value: "aiops_root_2026" + # - name: DATABASE_DBNAME + # value: "aiops" + # - name: REDIS_DRIVER + # value: "redis" + # - name: REDIS_HOST + # value: "10.10.10.75" volumeMounts: - name: config diff --git a/run.sh b/run.sh index 8d1f71c..8c1043c 100755 --- a/run.sh +++ b/run.sh @@ -12,7 +12,7 @@ # ./run.sh kubernetes status 查看资源状态 # ./run.sh kubernetes logs/exec 日志/进入容器 # -# 方式 3 — 独立二进制: +# 方式 3 — 独立二进制 (默认 --mode local, SQLite + redka): # ./run.sh build 编译独立二进制 (embed 前端) # ./run.sh binary upgrade 停服 → 清旧产物 → 重编译 → 后台启动 # ./run.sh binary start|stop|status