Why configuration files

  • 1, easy to edit, configuration is more centralized, convenient to modify, in the large volume of business system, through the configuration will be convenient for future generations to understand the architecture of the whole system
  • 2. Decouple the business code from the environment, and the environment configuration variables do not invade the code level
  • 3. It is convenient to switch between different environments

Second, ingoUse configuration files in

  • 1. Viper website address

  • 2. Local installation

    go get github.com/spf13/viper
    Copy the code
  • 3. Simply read the configuration file

    package main
    
    import (
    	"fmt"
    	"github.com/spf13/viper"
    )
    
    func main(a) {
    	v := viper.New()
    	v.SetConfigFile("config.yaml")
    	iferr := v.ReadInConfig(); err ! =nil {
    		fmt.Println("Failed to read configuration file", err)
    	}
    	fmt.Println(v.Get("name"))}Copy the code
  • 4. Create a config.yaml file at the same level as the file

    name: "test"
    Copy the code
  • 5. Run the file using the go run file name. If you run the file directly, an error will be reported

  • 6. It is recommended to run the project by right clicking after configuration

    package main
    
    import (
    	"fmt"
    	"github.com/spf13/viper"
    	"os"
    	"path"
    )
    
    func main(a) {
    	// Get the project directory
    	workDir, _ := os.Getwd()
    	v := viper.New()
      // directly concatenate file directory read
    	v.SetConfigFile(path.Join(workDir, "test/config.yaml"))
    	iferr := v.ReadInConfig(); err ! =nil {
    		fmt.Println("Failed to read configuration file", err)
    	}
    	fmt.Println(v.Get("name"))}Copy the code

Three, using the structure of the way read

  • 1. Simple use

    package main
    
    import (
    	"fmt"
    	"github.com/spf13/viper"
    	"os"
    	"path"
    )
    
    type ServerConfig struct {
    	Name string `mapstructure:"name"`
    }
    
    func main(a) {
    	// Get the project directory
    	workDir, _ := os.Getwd()
    	v := viper.New()
    	v.SetConfigFile(path.Join(workDir, "test/config.yaml"))
    	iferr := v.ReadInConfig(); err ! =nil {
    		fmt.Println("Failed to read configuration file", err)
    	}
    	serverConfig := ServerConfig{}
    	iferr := v.Unmarshal(&serverConfig); err ! =nil {
    		fmt.Println("Failed to resolve structure", err)
    	}
    	fmt.Println(serverConfig.Name)
    }
    Copy the code
  • 2, structure nesting, is very common mysql database configuration

    // define mysql
    type MySQLConfig struct {
    	Host string `mapstructure:"host"`
    	Port int `mapstructure:"port"`
    	Username string `mapstructure:"username"`
    	Password string `mapstructure:"password"`
    }
    type ServerConfig struct {
    	Name string `mapstructure:"name"`
    	// Use it nested, as in YAML
    	MySqlConfig MySQLConfig `mapstructure:"mysql"`
    }
    
    // Use it directly
    fmt.Println(serverConfig.MySqlConfig)
    
    Copy the code

Fourth, distinguish the development environment and production environment

  • 1. Configure the environment variables on the MAC. Export an environment variable in.bash_profile and close goland and open it again

    # vim .bash_profile
    export IS_DEV= true
    source .bash_profile 
    Copy the code
  • 2. Define methods to get environment variables directly

    func GetEnvInfo(env string) bool {
    	viper.AutomaticEnv()
    	return viper.GetBool(env)
    }
    func main(a) {
    	fmt.Println(GetEnvInfo("IS_DEV"))}Copy the code
  • 3. Create application.dev.yml and application.prod.yml files in the application directory to store the configurations in different environments

  • 4. Use environment variables to read the complete configuration code

    func GetEnvInfo1(env string) bool {
    	viper.AutomaticEnv()
    	return viper.GetBool(env)
    }
    
    // define mysql
    type MySQLConfig struct {
    	Host string `mapstructure:"host"`
    	Port int `mapstructure:"port"`
    	Username string `mapstructure:"username"`
    	Password string `mapstructure:"password"`
    }
    type ServerConfig struct {
    	Name string `mapstructure:"name"`
    	// Use it nested, as in YAML
    	MySqlConfig MySQLConfig `mapstructure:"mysql"`
    }
    
    func main(a) {
    	// Get the project directory
    	workDir, _ := os.Getwd()
    	isDev := GetEnvInfo1("IS_DEV")
    	configFileName := path.Join(workDir, "11.config/application.prod.yml")
    	if isDev {
    		configFileName = path.Join(workDir, "11.config/application.dev.yml")
    	}
    	v := viper.New()
    	v.SetConfigFile(configFileName)
    	iferr := v.ReadInConfig(); err ! =nil {
    		fmt.Println("Failed to read configuration file", err)
    	}
    	serverConfig := ServerConfig{}
    	iferr := v.Unmarshal(&serverConfig); err ! =nil {
    		fmt.Println("Failed to resolve structure", err)
    	}
    	fmt.Println(serverConfig.MySqlConfig)
    }
    Copy the code

Fifth, inginIntegrated configuration files in

  • 1. Create two xx.yml files in the same directory as main.go

  • Create a config, global, initialize folder

  • 3, in the config/config.go file, write using struct read configuration

    package config
    
    // define mysql
    type MySQLConfig struct {
    	Host string `mapstructure:"host"`
    	Port int `mapstructure:"port"`
    	Username string `mapstructure:"username"`
    	Password string `mapstructure:"password"`
    }
    type ServerConfig struct {
    	Name string `mapstructure:"name"`
    	// Use it nested, as in YAML
    	MySqlConfig MySQLConfig `mapstructure:"mysql"`
    }
    Copy the code
  • 4. Define global variables in the global/global.go file (you may need to obtain the configuration in one of the files in the whole project)

    var (
    	ServerConfig *config.ServerConfig = &config.ServerConfig{}
    )
    Copy the code
  • 5. Initialize the configuration in the Initialize /config directory

    func GetEnvInfo(env string) bool {
    	viper.AutomaticEnv()
    	return viper.GetBool(env)
    }
    
    func InitConfig(a) {
    	workDir, _ := os.Getwd()
    	isDev := GetEnvInfo("IS_DEV")
    	configFileName := path.Join(workDir, "11.config/application.prod.yml")
    	if isDev {
    		configFileName = path.Join(workDir, "11.config/application.dev.yml")
    	}
    	v := viper.New()
    	// How to set the file path
    	v.SetConfigFile(configFileName)
    	iferr := v.ReadInConfig(); err ! =nil {
    		panic(err)
    	}
    	err := v.Unmarshal(&global.ServerConfig)
    	iferr ! =nil {
    		fmt.Println("Failed to read configuration")
    	}
    	fmt.Println(&global.ServerConfig)
    }
    Copy the code
  • 6. Initialize the configuration file in mian. Go and print the information

    func main(a) {
    	// Initialize the configuration
    	initialize.InitConfig()
    	fmt.Println(global.ServerConfig.MySqlConfig)
    }
    Copy the code