Go Web实战-2.配置文件 - Go语言中文社区

Go Web实战-2.配置文件


        为了更好的集中管理项目的配置文件,引入了viper。git地址 https://github.com/spf13/viper

什么是viper,官方解释:

Viper is a complete configuration solution for Go applications including 12-Factor apps. It is designed to work within an application, and can handle all types of configuration needs and formats. It supports:

  • setting defaults
  • reading from JSON, TOML, YAML, HCL, and Java properties config files
  • live watching and re-reading of config files (optional)
  • reading from environment variables
  • reading from remote config systems (etcd or Consul), and watching changes
  • reading from command line flags
  • reading from buffer
  • setting explicit values

Viper can be thought of as a registry for all of your applications configuration needs.

         主要api:

  • Get(key string) : interface{}
  • GetBool(key string) : bool
  • GetFloat64(key string) : float64
  • GetInt(key string) : int
  • GetString(key string) : string
  • GetStringMap(key string) : map[string]interface{}
  • GetStringMapString(key string) : map[string]string
  • GetStringSlice(key string) : []string
  • GetTime(key string) : time.Time
  • GetDuration(key string) : time.Duration
  • IsSet(key string) : bool

        viper是国外大牛写的一个牛逼的配置管理库,支持的语言的也比较多,JSON, TOML, YAML, HCL, Java properties都可以,而且还能远程读取配置,这个做微服务配置中心挺合适。

          这里我还是用yaml来写配置参数。

安装

go get github.com/spf13/viper

主要步骤

  1. 写好配置文件
  2. 设置viper查找的文件目录
  3. 设置配置文件名称
  4. 读取参数

实现步骤

首先我们创建目录放配置文件和程序。


yaml文件夹里面是配置文件,param里面是参数模块。

我添加了两个参数模块,分别是应用参数和数据源参数,我们看一下application.yaml里面的参数:

application:
    mode: debug #gin的启动模式, debug or release or test
    server:
        port: 8080

datasource:
    #多数据源使用数据源名称做主键保存到参数列表
    user:   #key
            dialect: mysql
            url: jdbc:mysql://localhost:3306/base_user?allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8&useSSL=true
            username: root
            password: root
            maxIdle: 200
            maxOpen: 50
    admin: #key
            dialect: mysql
            url: jdbc:mysql://localhost:3306/base_admin?allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8&useSSL=true
            username: root
            password: root
            maxIdle: 200
            maxOpen: 50


InitConfig.go是参数配置的入口,其init在main导入config包后调用,InitConfig.go内容如下

type ConfigParam struct {
   App AppParam   //应用参数
   Dbs DbParam    //数据源参数
}
var Config ConfigParam

func init(){
   fmt.Println("[init config params]......")

   viper.SetConfigType("yaml")
   viper.SetConfigName("application") // name of config file (without extension)
   viper.AddConfigPath("./config/yaml")   // 配置文件路径,多次使用可以查找多个目录
   err := viper.ReadInConfig() // Find and read the config file
   if err != nil { // Handle errors reading the config file
      panic(fmt.Errorf("Fatal error config file: %s n", err))
      return
   }

   //加载配置
   Config.App.ReadConfig()
   Config.Dbs.ReadConfig()

   fmt.Println("[end init config params]......")
}

里面创建了个全局参数Config供应用调用。Config里面是两个模块的参数。

init里面首先设置了配置文件名称和路径,然后调用参数模块的ReadConfig方法加载参数。

先看AppParam的加载

type server struct {
   Mode string
   Port string
}

type AppParam struct {
   server
}

func (p *AppParam)ReadConfig(){

   //default config
   viper.SetDefault("application.mode", "debug")
   viper.SetDefault("application.server.port","8080")

   //read properties
   p.Mode = viper.GetString("application.mode")
   //注意server的port数字前面有个冒号
   p.Port = ":" + viper.GetString("application.server.port")

   fmt.Println("[Init AppParam Over]...", p)
}

这个比较简单,直接通过viper的方法读取配置文件里面的字符串。这里我们先给两个参数设置了默认值,当配置文件里面没有找到参数时viper会自动加载默认值。

然后是DbParam的加载

type datasource struct {
   Dialect  string
   Url      string
   Username string
   Password string
   MaxIdle  int
   MaxOpen  int
}

//多数据源支持,map[name]= db
type DbParam struct {
   //数据源数量
   Cnt int
   //数据源map
   Source map[string]datasource
}

func (p *DbParam) ReadConfig() {
   //default config
   //viper.SetDefault("ContentDir", "content")
   //viper.SetDefault("ContentDir", "content")

   p.Source = make(map[string]datasource)

   err := viper.UnmarshalKey("datasource", &p.Source)
   if err != nil {
      panic(err)
      return
   }
   p.Cnt = len(p.Source)
   fmt.Println("[Init DbParam Over]...", p)
}

viper内置了类似反序列化的工具,实际使用的是mapstructure这个库,主要功能就是把map转struct。

  • Unmarshal(rawVal interface{}) : error
  • UnmarshalKey(key string, rawVal interface{}) : error
type config struct {
	Port int
	Name string
	PathMap string `mapstructure:"path_map"`
}

var C config

err := Unmarshal(&C)
if err != nil {
	t.Fatalf("unable to decode into struct, %v", err)
}


这里把map转struct后保存到DbParam.source里面,使用“name”做数据源的主键, 然后就可以在其他地方使用参数了。

main函数里面使用参数

func main() {
   fmt.Println("[Server Starting]...")

   gin.SetMode(Config.App.Mode)

   //注册路由
   router := routers.InitRouter()

   //启动服务器
   router.Run(Config.App.Port)

   log.Println("Server stopped")
   //defer models.DbClose()
   os.Exit(0)
}

启动程序,查看打印的参数

[Init AppParam Over]... &{{debug :8080}}
[Init DbParam Over]... &{2 map[user:{mysql jdbc:mysql://localhost:3306/base_user?allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8&useSSL=true root root 200 50} admin:{mysql jdbc:mysql://localhost:3306/base_admin?allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8&useSSL=true root root 200 50}]}
[end init config params]......

版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/a1137475550/article/details/80072205
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。
  • 发表于 2020-03-01 20:57:56
  • 阅读 ( 1373 )
  • 分类:Go

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢