栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Go-13-配置文件读取

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Go-13-配置文件读取

目录

配置模块化

Viper

Viper的功能

Viper配置读取顺序

配置文件解析

新建配置文件

解析配置

主文件读取配置

主函数中增加配置初始化入口


目录

配置模块化

Viper

Viper的功能

Viper配置读取顺序

配置文件解析

新建配置文件

解析配置

主文件读取配置


配置模块化

为什么需要配置文件

  • 代码中对于一些可能会变化的内容,采用硬编码不便于维护
    • 如:监听的IP和端口
    • 如:数据库服务器地址和端口
    • 如:当前运行的模式(开发/测试)
    • ...

Viper

Viper的功能

Viper是国外大神spf13编写的开源配置解决方案,具有如下特性

  • 设置默认值
  • 可以读取如下格式的配置文件:JSON、TOML、YAML、HCL
  • 监控配置文件改动,并热加载配置文件
  • 支持直接设置配置项的值
  • 从环境变量读取配置
  • 从远程配置中心读取配置(etc/consul),并监控变动
    • etcd是一个分布式一致性的key-value存储技术,被用来做配置共享和服务发现
  • 从命令行flag读取配置
  • 从缓存中读取配置

Viper配置读取顺序

Viper可以同时从不同的位置读取配置,不同位置的配置具有不同的优先级,高优先级的配置会覆盖低优先级相同的配置,按优先级从高到低排列如下

  1. 通过viper.Set函数显示设置的配置
  2. 命令行参数
  3. 环境变量
  4. 配置文件
  5. Key/Value存储
  6. 默认值

配置文件解析

apiserver采用YAML格式的配置文件,采用YAML格式是因为YAML表达的格式更丰富,可读性更强

在初始化配置文件后,Viper也可以非常方便地读取多个层级的配置

读取配置只需要调用viper.GetString()、viper.GetInt()和viper.GetBool()等函数即可

新建配置文件

在apiserver/conf/config.yaml(默认配置文件名字固定为config.yaml)

runmode: debug                 # 开发模式, debug, release, test
addr: :8000                    # HTTP绑定端⼝
name: apiserver                # API Server的名字
url: http://127.0.0.1:8000     # pingServer函数请求的API服务器的ip:port
max_ping_count: 10             # pingServer函数try的次数

解析配置

在apiserver/config/config.go   

main 函数通过 config.Init 函数来解析并 watch 配置⽂件

package config

import (
    "log"
    "strings"
    "github.com/fsnotify/fsnotify"
    "github.com/spf13/viper"
)

// 定义Config结构体,Name为配置⽂件名
type Config struct {
    Name string
}

// 为结构体添加initConfig⽅法 => 初始化配置⽂件
// 函数的返回值当出错时,返回err;当没有出错时,返回nil(err的零值)
func (c *Config) initConfig() error {
    if c.Name != "" {
        // 如果指定了配置⽂件,则解析指定的配置⽂件
        viper.SetConfigFile(c.Name)
    } else {
        // 如果没有指定配置⽂件,则解析默认的配置⽂件(conf/config)
        viper.AddConfigPath("conf")
        viper.SetConfigName("config")
    }
 
    // 设置配置⽂件格式为YAML
    viper.SetConfigType("yaml") 
 
    // 读取匹配的环境变量
    viper.AutomaticEnv() 
 
    // 读取环境变量的前缀为APISERVER
    viper.SetEnvPrefix("APISERVER")
 
    // 设置环境变量的读取规则,把点号('.')映射成下划线('_')
    replacer := strings.NewReplacer(".", "_")
    viper.SetEnvKeyReplacer(replacer)
 
    // viper解析配置⽂件
    if err := viper.ReadInConfig(); err != nil {
        return err
    }
    return nil
}

// 监控配置⽂件变化并热加载程序
// 通过该函数的 viper 设置,可以使 viper 监控配置⽂件变更,如有变更则热更新程序
// 所谓热更新是指:可以不重启 API 进程,使 API 加载最新配置项的值
func (c *Config) watchConfig() {
    viper.WatchConfig()
    viper.OnConfigChange(func(e fsnotify.Event) {
    log.Printf("Config file changed: %s", e.Name)
    })
}


func Init(cfg string) error {
    c := Config{
    Name: cfg,
    }
 
    // 初始化配置⽂件
    if err := c.initConfig(); err != nil {
    return err
    }
    
    // 监控配置⽂件变化并热加载程序
    c.watchConfig()
    return nil
}

主文件读取配置

主函数中增加配置初始化入口
  • 在main.go文件中导入模块
    • "github.com/spf13/pflag"
    • "github.com/spf13/viper"
    • "apiserver/config"
  • 在main.go文件中导入模块
var (
    // pflag⽤于处理命令⾏参数
    // 定义命令⾏参数对应的变量
    // 参数1:配置名,参数2:配置选项,参数3:值,参数4:⽤法说明
    // ex: ./apiserver -c config.yaml
    cfg = pflag.StringP("config", "c", "", "apiserver config file path.")
)

func main() {
    // 解析命令⾏传过来的参数(如果不解析或没有指定就相当于使⽤默认值conf/config.yaml)
    pflag.Parse()
 
    // init config => 初始化配置
    if err := config.Init(*cfg); err != nil { 
    panic(err)
    } 
    
    // Set gin mode.=> 设置项⽬模式
    gin.SetMode(viper.GetString("runmode"))

    ....
}
替换原本硬编码的内容

在main函数中将相应的配置改成从配置文件读取,需要替换的配置见下图中红框部分

// apiserver/main.go

// 调用viper.GetString()  viper.GetInt()  viper.GetBool()

替换后代码为

运行启动apiserver
  • 解决依赖 go mod tidy
  • 运行代码,启动apiserver后端口为配置文件中指定的端口

在项目中使用配置文件内容

修改:apiserver/router/router.go

加载:import "github.com/spf13/viper"

添加

 

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1041086.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号