常见配置文件格式

日常开发中读取配置文件包含以下几种格式:

  • json 格式字符串
  • K=V 键值对
  • xml 文件
  • yaml 格式文件
  • toml 格式文件

由于我在平时对yaml格式配置比较钟爱,下面我主要介绍 yaml 格式配置文件的使用方式

1
go get gopkg.in/yaml.v2

yaml示例

1
2
3
4
5
6
7
8
9
10
11
server:
port: 9060
mode: 'release'
mysql:
user: root
password: '123456'
path: '127.0.0.1:3306'
database: 'test'
config: 'charset=utf8&parseTime=True&loc=Local'
driver: 'mysql'

初始版(config/config.go)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
package config
import (
"flag"
"fmt"
"io/ioutil"
"log"
"os"
"time"
"gopkg.in/yaml.v2"
)
type Yaml struct {
Server `yaml:"server"`
Mysql `yaml:"mysql"`
}
type Server struct {
Port int `yaml:"port"`
Mode string `yaml:"mode"`
}
type Mysql struct {
User string `yaml:"user"`
Password string `yaml:"password"`
Path string `yaml:"path"`
Database string `yaml:"database"`
Config string `yaml:"config"`
Driver string `yaml:"driver"`
}
var Conf *Yaml
func init() {
const defaultConfigFile = "app/config/config.yaml"
c := &Yaml{}
yamlConf, err := ioutil.ReadFile(*configFile)
if err != nil {
panic(fmt.Errorf("get yamlConf error: %s", err))
}
err = yaml.Unmarshal(yamlConf, c)
if err != nil {
log.Fatalf("config Init Unmarshal: %v", err)
}
log.Println("config yamlFile load Init success.")
Conf = c
}

进阶版(使用flag命令行自定义配置文件路径)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
package config
import (
"flag"
"fmt"
"io/ioutil"
"log"
"os"
"time"
"gopkg.in/yaml.v2"
)
type Yaml struct {
Server `yaml:"server"`
Mysql `yaml:"mysql"`
}
type Server struct {
Port int `yaml:"port"`
Mode string `yaml:"mode"`
}
type Mysql struct {
User string `yaml:"user"`
Password string `yaml:"password"`
Path string `yaml:"path"`
Database string `yaml:"database"`
Config string `yaml:"config"`
Driver string `yaml:"driver"`
}
var Conf *Yaml
func init() {
var defaultConfigFile = "app/config/config.yaml"
// 命令行通过增加c参数路径来覆盖默认路径,若不传,则使用默认
configFile := flag.String("c", defaultConfigFile, "help config path")
// 解析命令行参数
flag.Parse()
c := &Yaml{}
yamlConf, err := ioutil.ReadFile(*configFile)
if err != nil {
panic(fmt.Errorf("get yamlConf error: %s", err))
}
err = yaml.Unmarshal(yamlConf, c)
if err != nil {
log.Fatalf("config Init Unmarshal: %v", err)
}
log.Println("config yamlFile load Init success.")
Conf = c
}

进阶版(环境变量)

通常我的配置文件目录结构如下:

1
2
3
4
5
6
7
8
9
gin-app-strat
├── app
| ├── ...
| ├── config
| | ├── config.local.yaml
| | ├── config.dev.yaml
| | ├── config.prod.yaml
| | └── config.go
| ├── ...

config/config.dev.yaml文件样例:

1
2
3
4
5
6
7
8
9
10
11
server:
port: ${SERVER_PORT}
mode: ${SERVER_MODE}
mysql:
user: ${MYSQL_USER}
password: ${MYSQL_password}
path: ${MYSQL_PATH}
database: ${MYSQL_DB}
config: 'charset=utf8&parseTime=True&loc=Local'
driver: 'mysql'

使用 os.ExpandEnv 在给定的字符串中扩展环境变量:

我们只需要在环境变量中加入 yaml 中 ${} 里面的内容,就可以在运行时读取相应配置。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
package config
import (
"flag"
"fmt"
"io/ioutil"
"log"
"os"
"time"
"gopkg.in/yaml.v2"
)
type Yaml struct {
Server `yaml:"server"`
Mysql `yaml:"mysql"`
}
type Server struct {
Port int `yaml:"port"`
Mode string `yaml:"mode"`
}
type Mysql struct {
User string `yaml:"user"`
Password string `yaml:"password"`
Path string `yaml:"path"`
Database string `yaml:"database"`
Config string `yaml:"config"`
Driver string `yaml:"driver"`
}
var Conf *Yaml
func init() {
var defaultConfigFile = fmt.Sprintf("app/config/config.%s.yaml", os.Getenv("SERVER_ENV"))
yamlConf, err := ioutil.ReadFile(*configFile)
if err != nil {
panic(fmt.Errorf("get yamlConf error: %s", err))
}
yamlConf = []byte(os.ExpandEnv(string(yamlConf)))
c := &Yaml{}
err = yaml.Unmarshal(yamlConf, c)
if err != nil {
log.Fatalf("config Init Unmarshal: %v", err)
}
log.Println("config yamlFile load Init success.")
Conf = c
}

具体用法请参考github