This is the 8th day of my participation in the November Gwen Challenge. Check out the event details: The last Gwen Challenge 2021
Author: lomtom
Personal website: Lomtom.top,
Personal public account: Bosiao Yuan
Your support is my biggest motivation.
The Go series:
- Go (1) Basic introduction
- Go (ii) structure
- Go (3) Go configuration file
- Go (4) Redis operation
Those of you who are familiar with SpringBoot and then use Go will find that SpringBoot configuration files are really convenient
At Go, he doesn’t support this, so we’ll have to implement something like a SpringBoot profile ourselves.
Train of thought
Configuration files come in many forms, such as JSON, XML, YML, TOML, or key-value pairs.
Although there are various configuration files, the overall processing steps are generally the same
- Writing configuration files
- Write structures that correspond to configuration files
- Read the configuration file and load it into the appropriate structure
implementation
Because SpringBoot is used, YML files are convenient and concise, so yML files are used as an example here
Writing configuration files
Create a configuration file, name it as you wish, and ensure that the suffix is yML.
server:
port: 8000
runMode: debug # release debug
logLevel: debug # debug info warn error
database:
type: mysql
host: localhost
port: 32306
username: root
password: 123456
dbname: test
max_idle_conn: 10
max_open_conn: 30
conn_max_lifetime: 300
redis:
host: localhost
port: 32307
password:
db: 0
Copy the code
Here is similar to SpringBoot common configuration, set mysql, redis related Settings
Write structure
The structure needs to correspond to the hierarchy of YML and add YAML :”server” to facilitate system identification
var Server *server
var Database *database
var Redis *myRedis
type conf struct {
Svc server `yaml:"server"`
DB database `yaml:"database"`
RedisConfig myRedis `yaml:"redis"`
}
type server struct {
Port int `yaml:"port"`
RunMode string `yaml:"runMode"`
LogLevel string `yaml:"logLevel"`
}
type database struct {
Type string `yaml:"type"`
Host string `yaml:"host"`
Port string `yaml:"port"`
UserName string `yaml:"username"`
Password string `yaml:"password"`
DbName string `yaml:"dbname"`
MaxIdleConn int `yaml:"max_idle_conn"`
MaxOpenConn int `yaml:"max_open_conn"`
ConnMaxLifetime int `yaml:"conn_max_lifetime"`
}
type myRedis struct {
Host string `yaml:"host"`
Port string `yaml:"port"`
Password string `yaml:"password"`
DB int `yaml:"db"`
}
Copy the code
Of course, they can also rewrite their String method, so that when the project starts, it can be ordered to print, and also easier to see if the configuration file has been loaded successfully
func (c conf) String(a) string {
return fmt.Sprintf("%v\n%v\n%v", c.Svc, c.DB, c.RedisConfig)
}
func (s server) String(a) string {
return fmt.Sprintf("server : \n"+
"\tport : %v \n"+
"\tRunMode : %v", s.Port, s.RunMode)
}
func (m database) String(a) string {
return fmt.Sprintf("database : \n"+
"\ttype : %v \n"+
"\thost : %v \n"+
"\tport : %v \n"+
"\tusername : %v \n"+
"\tpassword : %v \n"+
"\tdbname : %v \n"+
"\tmax_idle_conn : %v \n"+
"\tmax_open_conn : %v \n"+
"\tconn_max_lifetime : %v",
m.Type, m.Host, m.Port, m.UserName, m.Password, m.DbName, m.MaxOpenConn, m.MaxIdleConn, m.ConnMaxLifetime)
}
func (r myRedis) String(a) string {
return fmt.Sprintf("redis : \n"+
"\thost : %v \n"+
"\tport : %v \n"+
"\tPassword : %v \n"+
"\tdb : %v",
r.Host, r.Port, r.Password, r.DB)
}
Copy the code
Read the file
Big time!!
Premise: Introduce dependencies
go get gopkg.in/yaml.v2
Copy the code
All you need to do is read the information from the configuration file and bind it to the appropriate structure.
func InitConf(dataFile string) {
// Resolve the problem that the configuration file cannot be obtained in the relative path
_, filename, _, _ := runtime.Caller(0)
filePath := path.Join(path.Dir(filename), dataFile)
_, err := os.Stat(filePath)
iferr ! =nil {
log.Printf("config file path %s not exist", filePath)
}
yamlFile, err := ioutil.ReadFile(filePath)
iferr ! =nil {
log.Printf("yamlFile.Get err #%v ", err)
}
c := new(conf)
err = yaml.Unmarshal(yamlFile, &c)
iferr ! =nil {
log.Printf("Unmarshal: %v", err)
}
log.Printf("load conf success\n %v", c)
// Bind to externally accessible variables
Server = &c.Svc
Database = &c.DB
Redis = &c.RedisConfig
}
Copy the code
If the file cannot be read using relative path, you can add the following code
_, filename, _, _ := runtime.Caller(0)
filePath := path.Join(path.Dir(filename), dataFile)
Copy the code
use
Load the configuration file, which can be loaded in the init method (the project starts automatically without calling)
func init(a) {
// Load the configuration file
config.InitConf(".. /.. /config/app-dev.yaml")}Copy the code
Note that the path is the path of the reading configuration file tool relative to the configuration file, not the path of the init method relative to the configuration file
├ ─ config │ └ ─ app - dev. Yaml └ ─ util │ └ ─ config │ └ ─ ConfigUtil. Go └ ─ main. GoCopy the code
Call the structure directly when using it
For example, you need to specify gin mode, which corresponds to server. RunMode, and so on
func InitRouters(a) *gin.Engine {
r := gin.Default()
gin.SetMode(config.Server.RunMode)
return r
}
Copy the code