Golang之接入配置模块

Table of contents

  1. 1. 接入配置模块
    1. 1.1. 业务配置的通用理论:来源
    2. 1.2. 业务配置的通用理论:优先级
    3. 1.3. 业务配置的通用理论:两次加载
    4. 1.4. viper
      1. 1.4.1. 初始化viper
      2. 1.4.2. 读取viper配置
      3. 1.4.3. 设置viper默认值
      4. 1.4.4. viper动态读取配置
      5. 1.4.5. viper读取远程配置中心
        1. 1.4.5.1. 安装etcd和etcdctl

接入配置模块

业务配置的通用理论:来源

配置的来源有这么几类

  • 启动参数:某一次运行的参数,可以在这里提供,典型的就是命令行工具
  • 环境变量:具体实例有关的参数可以放在环境变量中
  • 本地配置文件:当下环境所需要的通用配置
  • 远程配置中心:与本地配置文件互相补充,除了满足启动服务的最小配置,剩下的配置都可以放在远程配置中心

优先使用配置文件,大规模服务器集群可以考虑使用远程配置中心

业务配置的通用理论:优先级

有的时候,同一个配置项有多个来源,这个时候就需要根据优先级敲定一个唯一的来源

img

可以有下列这番排列

  • 命令行:毕竟是自己写的
  • 环境变量:本机电脑上的环境变量也是自己配置的
  • 配置文件:可能是同事写的,用Git同步过来了
  • 远程配置中心

业务配置的通用理论:两次加载

在使用远程配置中心时,一般需要有两次加载的过程

  • 第一次加载最基本的配置,包括
    • 远程配置中心的连接信息
    • 日志相关配置
  • 第二次加载则是完全加载
    • 读取系统所需要的所有依赖
    • 覆盖第一次加载的配置

简单地,第一次加载就是加载最基本功能第二次加载就是完全加载并对第一次加载配置进行覆盖

viper

初始化viper

https://github.com/spf13/viper

首先准备好配置本地文件

img

接着使用viper读取本地的配置文件,具体有两种初始化viper的方法

  • 直接指定目标配置文件的路径

    • viper.SetConfigFile():加载配置文件

    • viper.ReadInConfig():读取配置文件内容

    • // 设定viper将要读取的文件
      // viper从当前工作目录下进行定位
      viper.SetConfigFile("config/dev.yaml")
      err := viper.ReadInConfig()
      if err != nil {
          panic(err)
      }
      
      
      - 分别指定目标配置文件的类型、名称、子目录
      
        - `viper.SetConfigType()`、`viper.SetConfigName()`、`viper.AddConfigPath()`:加载配置文件
      
        - `viper.ReadInConfig()`:读取配置文件内容
        
        - ```Go
          // 设定viper将要读取的文件
          // viper从当前工作目录下进行定位
          viper.SetConfigType("yaml")
          viper.SetConfigName("dev")
          viper.AddConfigPath("config")
          err := viper.ReadInConfig()
          if err != nil {
              panic(err)
          }

值得注意的是,不管是向viper中直接传入路径还是子目录,都是从当前Go的工作目录开始定位的

可以在Goland IDE中查看working directory

读取viper配置

从viper中读取某一配置项有两种常用的方法

  • 直接读取某一个配置
  • 定义一个结构体,用于接收所有的配置项

第二种方法比较推荐使用,我们可以在IOC中,也就是需要使用配置项的初始化的地方,定义一个内部结构体用于接收所有的配置项

有两个注意点:

  1. 内部结构体字段要求包外能够访问(即首字母大写)
  2. 指明将要读取的数据格式以及字段名称
type Config struct {
	// 指明读取数据格式以及字段名称
	// 结构体内的字段要保证包外能访问,否则无法成功初始化
	DSN string `yaml:"dsn"`
}
var config Config
// 指定要读取的key
err := viper.UnmarshalKey("db", &config)
if err != nil {
	panic(err)
}

设置viper默认值

有的时候配置文件中缺少一些必要的配置项信息,这个时候就需要使用上viper的配置默认值。例如,如果我忘记了写DB的配置,那么就应该默认使用localhost:3306

在viper中有两种实现默认值的方案:

  • 使用viper的SetDefault()方法
  • 利用结构体,在UnmarshalKey()之前设置好默认值
    • 推荐这种,因为可以把默认值放在初始化的地方

viper动态读取配置

一般而言,一个项目可能处在多个环境中,例如:开发环境、测试环境、线上环境,在不同环境中必然需要使用到不同的配置信息,那么这就会要求我们能够动态地读取配置

我们可以在启动项目时传入一个config参数,这个config参数就是此次将读取的配置文件路径

// 初始化配置文件路径指针,并设定默认值
cfile := pflag.String("config", "config/hello.yaml", "配置文件路径")
// 接收config参数
pflag.Parse()
viper.SetConfigFile(*cfile)
err := viper.ReadInConfig()

可以在Goland IDE中设置config参数

viper读取远程配置中心

安装etcd和etcdctl

使用docker compose安装etcd

etcdctl没有安装成功,不明所以

path用于区别其他使用etcd的应用

image-20240901152107902