Golang 中可以像 Laravel 一样实时更新 Config 变量吗?

背景

近期重构 PHP 项目为 Golang 时遇到这样一个问题,看看大佬们有没有遇到过,或更加优秀的办法。

我们需要给系统建立一个配置表,存储一些常用但不经常改动的配置(需要改动),如存:smtp 信息、是否开启审核、是否xxx、等(运营人员可以改动)。

白话说:这个表类似于 CMS\WordPress 后台系统,能改某些配置文件。

旧项目实现

旧项目 PHP 代码如下实现,在初始化时,将配置表数据直接写入 config 中,由于语言特性,config 可做到实时更新。(数据库更新)
Golang 中可以像 Laravel 一样实时更新 Config 变量吗?

新项目实现

我们考虑了两种方案实现:

  1. 在 Golang 中我们使用的是 Gin 框架,考虑存在 Redis 中,每次获取的时候实时去读,但在获取多个配置时要多次去从 Redis 获取,浪费多次网络请求,且后台管理系统更新也不太方便;
  2. 由程序员去配置,写到配置文件中,每次更改都需要程序员去发版改动配置文件;

理想中的逻辑

我们希望配置像 PHP 一样,修改数据库配置表后,能够写到一个全局函数或变量中(存在内存中),后台管理系统修改,业务逻辑可以全局函数或变量中在直接获取。

目前没有想到合适的方法实现,大家有类似的方法吗?

讨论数量: 16

用 github.com/spf13/viper ,用配置中心驱动。或者就是直接用配置文件,用它带的文件变化事件实时更新配置

1个月前 评论
陈大剩 (楼主) 1个月前
deatil (作者) 1个月前
deatil (作者) 1个月前
  • 可以监听某个信号,收到信号后重新load配置文件,后面的请求就是新的配置。

file

package main

import (
    "fmt"
    "os"
    "os/signal"
    "syscall"
    "time"
)

type Config struct {
    AppName string
}

func main() {
    cfg := &Config{"App1"}
    fmt.Printf("PID: %d\n", os.Getpid())
    go func() {
        for {
            time.Sleep(time.Second * 3)
            fmt.Println(cfg.AppName)
        }
    }()
    var ch = make(chan os.Signal)
    signal.Notify(ch, syscall.SIGUSR2)
    for s := range ch {
        if s == syscall.SIGUSR2 {
            cfg.AppName = "App2"
            // todo reload config
        }
    }
}
  • 还可以用一个接口来更新全局变量的值,这个全局变量存储你的配置
1个月前 评论
陈大剩 (楼主) 1个月前

你不如存到数据库,然后缓存一份到内存里,用的时候优先读缓存,缓存没有读数据库,更新的时候存到数据库顺便把缓存的也更新了,省得你读redis也耗时间,改起来也方便,重启了数据也还在

1个月前 评论
陈大剩 (楼主) 1个月前
lchola (作者) 1个月前
陈大剩 (楼主) 1个月前

如果你是文件的话,可以使用这个库:github.com/fsnotify/fsnotifyfsnotify.NewWatcher() 会 初始化一个 Watcher 它可以监听文件的变化,做到配置的及时更新

如果你是通过管理后台管理配置的话,那么建议 ETCD,我们之前就是使用 ETCD 搭建的配置中心,然后通过 ETCD 一键推送配置至测试环境、灰度环境、线上环境

1个月前 评论

还不如保留config表的能力到golang上面去,修改/删除更新下缓存即可。

1个月前 评论
陈大剩 (楼主) 4周前

这要是Java,直接上配置中心就行了,何必用这个了

4周前 评论
TommyTu

之前有 gin 的项目是 Viper + Nacos, 可以实现你这个需求

5天前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!