V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
ppmoon
V2EX  ›  Go 编程语言

golang 应用实时更新配置文件,热更新配置文件第三方包

  •  
  •   ppmoon · 2018-07-14 11:42:32 +08:00 · 3391 次点击
    这是一个创建于 2318 天前的主题,其中的信息可能已经有所发展或是发生改变。

    做了一个 golang 应用实时更新配置的第三方包欢迎大家点评和 star https://github.com/ppmoon/golang-redis-config

    GRC - golang redis config

    GRC 是一款使用 golang redis 对应用程序的配置文件进行热更新的一款软件,方便在应用程序启动的过程当中实时更新我们的配置文件。

    使用

    可以参考测试文件

    //使用 NewGrc 实例化 第一个参数是.env 文件 第二个参数是 redis 地址,第三个参数是 redis 密码,第四个参数是 redis 分区号。0 就是默认的数据库
    //.env 是使用 kv 来设置参数哒
    g := grc.NewGrc(".env","localhost:6379","",0)
    //监听.env 变化。注意:这里需要单独启动一个 go 程监听文件变化,否则会影响你的主要 go 程。
    go g.WatchFile()
    //GetItem 获得配置文件。
    config := g.GetItem("ack")
    fmt.Println(config)
    

    为什么设计这样一个包?

    golang 这种编译型语言无法像 PHP 一样实时的热更新配置数据。为了让 golang 更加简单的热更新配置文件所以设计制作了 GRC 这个热更新配置文件的包。

    思路

    具体思路是使用 redis 内存数据库作为配置的存放容器,然后让 golang 直接读取 redis 的数据作为配置数据,更新配置的时候,我们只要去更新 redis 里面的数据,golang 应用程序就可以实时更新了。但是平凡的去操作数据库是危险的,所以本程序额外使用了一个.env 的配置文件和 php laravel 的配置文件类似,GRC 会新启动一个 go 程去监听.env 的变化,GRC 初始化的时候会先将.env 的数据以 KV 的形式存入 redis,如果.env 发生变化,GRC 会更新 redis 当中的配置列表。这样做的好处是,我们可以在外部使用编辑器更新配置文件,同时又不同 golang 程序去读取.env 文件,相比读取磁盘上的配置文件,读取 redis 内存当中的数据速度要快很多,否则频繁的打开和关闭.env 会造成磁盘性能的损耗。

    不使用 redis 作为配置容器的一些常规方法

    1.我们可以在项目目录当中配置一个 config.go 的文件,每次修改的时候修改这个文件的内容,然后重新编译项目。 2.我们可以写一个外部的 yaml 文件,每次都让 golang 应用去读取 yaml 读取配置。这样也可以热更新,但是问题就像上面说的,会频繁的触发磁盘 IO 操作。 3.我们可以让 golang 应用监听一个配置 channel,然后我们用 golang 编写另外一个 cli 程序如果需要修改配置的时候就向这个管道写入数据,然后 golang 应用就去更新配置变量。

    以上是我可以想到的方法都有利有弊,相对来说我觉得使用 redis 更省事,所以 GRC 的方案也不错。以上欢迎指教和 star。

    8 条回复    2018-08-11 23:54:10 +08:00
    gamexg
        1
    gamexg  
       2018-07-14 12:13:11 +08:00 via Android   ❤️ 1
    配置更新是原子的吗?

    频繁读取文件一般不会造成频繁的读取操作,操作系统会有缓存。
    go 协程无法跨进程通信。
    heww
        2
    heww  
       2018-07-14 13:27:19 +08:00 via iPhone
    go-micro 的 go-config 了解一下。
    ppmoon
        3
    ppmoon  
    OP
       2018-07-14 15:14:07 +08:00
    @gamexg 感谢学习了
    Immortal
        4
    Immortal  
       2018-07-14 15:37:33 +08:00
    以前做法是启了一个协程监听配置文件改动 改动了做 reload 操作的处理
    ppmoon
        5
    ppmoon  
    OP
       2018-07-14 23:41:05 +08:00
    @heww 看了一下,好酷
    pythonee
        6
    pythonee  
       2018-08-11 23:30:44 +08:00
    @gamexg 这个原子性是指?
    我觉得热更新最难的就是,配置更新的那一瞬间,应用的上下文发生变化,业务逻辑能否保证正确吗(对当前的任务的影响怎么评估呢)
    pythonee
        7
    pythonee  
       2018-08-11 23:31:11 +08:00
    @gamexg 之前一直听说 lisp 可以做到这个东西,但是不知道是什么原理
    gamexg
        8
    gamexg  
       2018-08-11 23:54:10 +08:00
    @pythonee #6

    >将.env 的数据以 KV 的形式存入 redis
    在更新配置时如果同时读取配置不同的项,是否会部分项是新版本部分项是老版本?

    没做过太强关联的,一般都是老请求继续用老配置,新请求使用新配置。
    每个新请求收到时会获得当前配置,一直用到这个请求结束。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2742 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 78ms · UTC 07:39 · PVG 15:39 · LAX 23:39 · JFK 02:39
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.