• golang读取conf文件的两种方式(ini和Viper)



    前言

    平时写项目都是习惯于将什么Mysql,Redis,Kafka等这些需要配置的配置信息单独用一个conf文件来进行存放,以便管理


    一、ini包

    首先一个方法是比较轻量级的方法,就是ini包里的方法,很简单便捷


    1、下载

    go get gopkg.in/ini.v1进行下载

    2、使用方法

    一般将配置信息使用在这里插入图片描述
    这个ini文件进行存储
    格式如下

    [database]
    Db = mysql
    DbHost = 127.0.0.1
    DbPort = 3306
    DbUser = root
    DbPassWord = ******
    DbName = ****
    
    [kafka]
    address =127.0.0.1:9092
    topic = web_log
    
    [collect]
    logfile_path =d:\logs\s4.log
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    使用这个包我们一般有两种方式


    法一:简单方法

    file, err := ini.Load("conf/config.ini")
    if err != nil {
    	fmt.Println("配置文件读取错误,请检查文件路径:", err)
    }
    
    • 1
    • 2
    • 3
    • 4

    读取到配置文件内容到file中

    	DbHost = file.Section("database").Key("DbHost").String()
    	DbPort = file.Section("database").Key("DbPort").String()
    	DbUser = file.Section("database").Key("DbUser").String()
    	DbPassWord = file.Section("database").Key("DbPassWord").String()
    	DbName = file.Section("database").Key("DbName").String()
    	fmt.Println(DbHost, DbPort, DbUser, DbPassWord, DbName)
    // 127.0.0.1 3306 root 123456 ginblog
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    这样就可以拿到具体的key了

    而一般来讲为了模块化都会将不同技术的配置信息封装到不同的函数里进行模块化管理
    eg:

    		func LoadData(file *ini.File) {...}
    		func LoadKafka(file *ini.File) {...}
    		func LoadRedis(file *ini.File) {...}
    
    • 1
    • 2
    • 3

    法二:结构体反射

    把配置文件里的信息提前使用结构体封装然后进行反射

    type Config struct {
    	KafkaConfig `ini:"kafka"`
    	Collect     `ini:"collect"`
    	Etcd        `ini:"etcd"`
    }
    
    type KafkaConfig struct {
    	Address string `ini:"address"`
    	Topic   string `ini:"topic"`
    }
    
    type Collect struct {
    	LogFilePath string `ini:"logfile_path"`
    }
    
    type Etcd struct {
    	Address     string `ini:"address"`
    	Collect_key string `ini:"collect_key"`
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    然后使用结构体的tag进行反射读取配置信息

    var configObj = new(Config)
    err := ini.MapTo(configObj, "./conf/Config.ini")
    if err != nil {
    	logrus.Error("config failed err:", err)
    	return
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    这样操作一番所有的配置信息都拿到了在configObj中,比法一更加的一步到位


    二、viper配置管理

    viper相较于法一的包就比较重量级了,比较的完善,现如今也是go比较流行的完整配置解决方案


    1、下载

    go get github.com/spf13/viper进行安装viper包


    2、viper的特点

    viper的特性如下

    设置默认值
    从JSON、TOML、YAML、HCL、envfile和Java properties格式的配置文件读取配置信息
    实时监控和重新读取配置文件(可选)
    从环境变量中读取
    从远程配置系统(etcd或Consul)读取并监控配置变化
    从命令行参数读取配置
    从buffer读取配置 显式配置值

    而本文章主要讲解viper从配置文件读取信息并实时监控配置文件进行热加载
    若对其他内容有兴趣可以看看李文周老师博客进行了解

    3、使用方法

    跟ini一样一般创建一个conf文件存储配置信息,本次例子用yaml文件做例子

    在这里插入图片描述

    mysql:
      host: 127.0.0.1
      port: 3306
      user: "root"
      password: "****"
      dbname: "****"
      max_open_conns: 20
      max_idle_conns: 20
    redis:
      host: 127.0.0.1
      port: 6379
      password: ""
      db: 0
      pool_size: 100
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    读取

    首先一样的也是建结构体进行反射

    type AppConfig struct {
    	*MySQLConfig `mapstructure:"mysql"`
    	*RedisConfig `mapstructure:"redis"`
    }
    type MySQLConfig struct {
    	Host         string `mapstructure:"host"`
    	User         string `mapstructure:"user"`
    	Password     string `mapstructure:"password"`
    	DB           string `mapstructure:"dbname"`
    	Port         int    `mapstructure:"port"`
    	MaxOpenConns int    `mapstructure:"max_open_conns"`
    	MaxIdleConns int    `mapstructure:"max_idle_conns"`
    }
    
    type RedisConfig struct {
    	Host         string `mapstructure:"host"`
    	Password     string `mapstructure:"password"`
    	Port         int    `mapstructure:"port"`
    	DB           int    `mapstructure:"db"`
    	PoolSize     int    `mapstructure:"pool_size"`
    	MinIdleConns int    `mapstructure:"min_idle_conns"`
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    然后就是使用viper进行读取

    	viper.SetConfigFile("config配置文件绝对路径")
    	err = viper.ReadInConfig() // 读取配置信息
    	if err != nil {
    		// 读取配置信息失败
    		fmt.Printf("viper Read Config failed, err:%v\n", err)
    		return
    	}
    
    	// 把读取到的配置信息反序列化到 Conf 变量中
    	if err := viper.Unmarshal(Conf); err != nil {
    		fmt.Printf("viper Unmarshal failed, err:%v\n", err)
    	}
    
    	viper.WatchConfig()  // 对配置文件进行监视,若有改变就重新反序列到Conf中
    	viper.OnConfigChange(func(in fsnotify.Event) {
    		fmt.Println("配置文件修改了...")
    		if err := viper.Unmarshal(Conf); err != nil {
    			fmt.Printf("viper.Unmarshal failed, err:%v\n", err)
    		}
    	})
    	return
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    这就是使用viper对配置文件进行管理的方法

    总结

    不管是ini还是viper,可以看到都是非常方便的,但是viper的功能更加完善,更适用于企业级开发吧,ini就适合小型项目的使用就我个人感觉

  • 相关阅读:
    Ae 动态图形模板
    Springboot JSON 转换:Jackson篇
    vs+qt项目gitlab-ci 配置
    tinyxml 代码解读
    Ubuntu18.04 ros 安装ZED SDK---基于x86架构
    P1281 书的复制
    快速安装NGINX
    14:00面试,14:06就出来了,问的问题有点变态。。。
    如何优雅的退出线程(condition_variable )
    无人机RTMP推流EasyDSS直播平台推流成功,不显示直播按钮是什么原因?
  • 原文地址:https://blog.csdn.net/qq_51898139/article/details/126482375