配置文件

配置对象我们推荐使用单例方式获取,单例对象将会按照文件后缀toml/yaml/yml/json/ini/xml/properties文自动检索配置文件。默认情况下会自动检索配置文件config.toml/yaml/yml/json/ini/xml/properties并缓存,配置文件在外部被修改时将会自动刷新缓存。

如果想要自定义文件格式,可以通过SetFileName方法修改默认读取的配置文件名称(如:default.yaml, default.json, default.xml等等)。例如,我们可以通过以下方式读取default.yaml配置文件中的数据库database配置项。

文件可以是一个具体的文件名称或者完整的文件绝对路径。

我们可以通过多种方式修改默认文件名称:

  1. 通过配置管理方法SetFileName修改。
  2. 修改命令行启动参数 - gf.gcfg.file
  3. 修改指定的环境变量 - GF_GCFG_FILE

假如我们的执行程序文件为main,那么可以通过以下方式修改配置管理器的配置文件目录(Linux下):

  1. 通过单例模式

    1. g.Cfg().GetAdapter().(*gcfg.AdapterFile).SetFileName("default.yaml")
  2. 通过命令行启动参数

    1. ./main --gf.gcfg.file=config.prod.toml
  3. 通过环境变量(常用在容器中)

      1. 使用genv模块来修改环境变量:

    配置目录

    gcfg配置管理器支持非常灵活的多目录自动搜索功能,通过SetPath可以修改目录管理目录为唯一的目录地址,同时,我们推荐通过AddPath方法添加多个搜索目录,配置管理器底层将会按照添加目录的顺序作为优先级进行自动检索。直到检索到一个匹配的文件路径为止,如果在所有搜索目录下查找不到配置文件,那么会返回失败。

    gcfg配置管理对象初始化时,默认会自动添加以下配置文件搜索目录:

    1. 当前工作目录及其下的configmanifest/config目录:例如当前的工作目录为/home/www时,将会添加:
      1. /home/www
      2. /home/www/manifest/config
    2. 当前可执行文件所在目录及其下的configmanifest/config目录:例如二进制文件所在目录为/tmp时,将会添加:
      1. /tmp
      2. /tmp/config
      3. /tmp/manifest/config
    3. 当前main源代码包所在目录及其下的configmanifest/config目录(仅对源码开发环境有效):例如main包所在目录为/home/john/workspace/gf-app时,将会添加:
      1. /home/john/workspace/gf-app
      2. /home/john/workspace/gf-app/config
      3. /home/john/workspace/gf-app/manifest/config

    注意这里修改的参数必须是一个目录,不能是文件路径。

    我们可以通过以下方式修改配置管理器的配置文件搜索目录,配置管理对象将会只在该指定目录执行配置文件检索:

    1. 通过配置管理器的SetPath方法手动修改;
    2. 修改命令行启动参数 - gf.gcfg.path
    3. 修改指定的环境变量 - GF_GCFG_PATH

    假如我们的执行程序文件为main,那么可以通过以下方式修改配置管理器的配置文件目录(Linux下):

    1. 通过单例模式

      1. g.Cfg().GetAdapter().(*gcfg.AdapterFile).SetPath("/opt/config")
    2. 通过命令行启动参数

        • 启动时修改环境变量:

          1. GF_GCFG_PATH=/opt/config/; ./main
        • 使用genv模块来修改环境变量:

      内容配置

      gcfg包也支持直接内容配置,而不是读取配置文件,常用于程序内部动态修改配置内容。通过以下包配置方法实现全局的配置:

      1. func (c *AdapterFile) SetContent(content string, file ...string)
      2. func (c *AdapterFile) GetContent(file ...string) string
      3. func (c *AdapterFile) ClearContent()

      需要注意的是该配置是全局生效的,并且优先级会高于读取配置文件。因此,假如我们通过SetContent("v = 1", "config.toml")配置了config.toml的配置内容,并且也同时存在config.toml配置文件,那么只会使用到SetContent的配置内容,而配置文件内容将会被忽略。

      层级访问

      在默认提供的文件系统接口实现下,gcfg组件支持按层级获取配置数据,层级访问默认通过英文.号指定,其中pattern参数和 通用编解码-gjsonpattern参数一致。例如以下配置(config.yaml):

      1. server:
      2. address: ":8199"
      3. serverRoot: "resource/public"
      4. database:
      5. default:
      6. link: "mysql:root:12345678@tcp(127.0.0.1:3306)/focus"
      7. debug: true

      例如针对以上配置文件内容的层级读取:

      1. // :8199
      2. g.Cfg().Get("server.address")
      3. g.Cfg().Get("database.default.debug")

      注意事项

      大家都知道,在Golang里面,map/slice类型其实是一个”引用类型”(也叫”指针类型”),因此当你对这种类型的变量 键值对/索引项 进行修改时,会同时修改到其对应的底层数据。从效率上考虑,gcfg包某些获取方法返回的数据类型为时,没有对其做值拷贝,因此当你对返回的数据进行修改时,会同时修改gcfg对应的底层数据。

      例如:

      检测更新