Go 配置文件
类似 PHP的php.ini文件 Nginx的server.conf 文件
Go 项目配置文件 很多选择 如 JSON文件/INI文件/YAML文件/TOML文件等
对应的Golang处理库
encoding/json 标准库中的包 处理JSON配置文件 缺点是不能加注释
gcfg 处理 INI配置文件
toml 处理 TOML配置文件
viper 处理 JSON / TOML / YAML / HCL / Java properties配置文件
toml 使用
# This is a TOML document.title = "TOML Example"
[owner]
name = "Tom Preston-Werner"
dob = 1979-05-27T07:32:00-08:00 # First class dates
[database]
server = "192.168.1.1"
ports = [ 8001, 8001, 8002 ]
connection_max = 5000
enabled = true
[servers]
# Indentation (tabs and/or spaces) is allowed but not required
[servers.alpha]
ip = "10.0.0.1"
dc = "eqdc10"
[servers.beta]
ip = "10.0.0.2"
dc = "eqdc10"
[clients]
data = [ ["gamma", "delta"], [1, 2] ]
# Line breaks are OK when inside arrays
hosts = [ "alpha", "omega"]
格式灵活 数字 字符串 布尔等简单类型 数组 map等 复杂的类型 TOML语言 文档 //github.com/toml-lang/toml
使用配置文件来定义Go 配置 struct
type tomlConfig struct {Title string
Owner ownerInfo
DB database `toml:"database"`
Servers map[string]server
Clients clients
}
type ownerInfo struct {
Name string
Org string `toml:"organization"`
Bio string
DOB time.Time
}
type database struct {
Server string
Ports []int
ConnMax int `toml:"connection_max"`
Enabled bool
}
type server struct {
IP string
DC string
}
type clients struct {
Data [][]interface{}
Hosts []string
}
只需要将文件配置 内容转成Go 可用的struct实例 即可
var config tomlConfig
filePath := "/your/path/config.toml"
if _, err := toml.DecodeFile(filePath, &config); err != nil {
panic(err)
}
这样config就是拥有TOML文件内容的tomlConfig 实例 直接使用
配置的单例模式
项目 配置文件 只需要解析一次 可以使用单例模式 config 解析package config
var ( cfg * tomlConfig
once sync.Once
)
func Config() *tomlConfig {
once.Do(func() {
filePath, err := filepath.Abs("./ch3/config.toml")
if err != nil {
panic(err)
}
fmt.Printf("parse toml file once. filePath: %s\n", filePath)
if _ , err := toml.DecodeFile(filePath, &cfg); err != nil {
panic(err)
}
})
return cfg
}
使用 sync.Once 的 Do 方法 Do 方法当且仅当 第一次被调用时 才执行函数
如果 once.Do(f) 被多次调用 只有第一次调用会执行f 即使f每次调用Do 提供的f值不同
需要给每个要执行仅一次的函数 建立Once类型的实例 保证 tomlConfig对象 是单例模式 只需解析一次 在任何地方调用
fmt.Println(config.Config().DB.Server)// 配置中DB的IP
fmt.Println(config.Config().Owner.Name)// 配置中Owner的名字
配置的更新
常驻的项目(如http server) 希望能够提供 更新配置的功能 平滑的替换掉配置 不需要重启项目 只需要起一个协程 监视 定义好的信号如果接收到信号就重新加载配置
s := make(chan os.Signal, 1)
signal.Notify(s, syscall.SIGUSR1)
go func() {
for {
<-s
config.ReloadConfig()
log.Println("Reloaded config")
}
}()
监视了syscall.SIGUSR1信号 其值是30 接收到信号就执行config.ReloadConfig()方法 config中方法变动
func Config() *tomlConfig {
once.Do(ReloadConfig)
cfgLock.RLock()
defer cfgLock.RUnlock()
return cfg
}
func ReloadConfig() {
filePath, err := filepath.Abs("./ch3/config.toml")
if err != nil {
panic(err)
}
fmt.Printf("parse toml file once. filePath: %s\n", filePath)
config := new(tomlConfig)
if _ , err := toml.DecodeFile(filePath, config); err != nil {
panic(err)
}
cfgLock.Lock()
defer cfgLock.Unlock()
cfg = config
}
原来加载配置的代码放到ReloadConfig方法中 在给变量cfg赋值时 加了读写锁 以保证安全
在Config方法中获取cfg的时候加了读锁 防止在读的时候 也在写入 导致配置错乱
启动server之后 可以通过如下shell命令更新配置 kill -30 6666
其中的6666是go server的进程号 执行这条命令之后 会向go server发送syscall.SIGUSR1的信号 从而触发更新配置的动作
POSIX信号
Linux 使用34-64信号用作实时系统中 命令 man 7 signal 官方的信号介绍在POSIX.1-1990标准中定义的信号列表:
信号 值 动作 说明
SIGHUP 1 Term 终端控制进程结束(终端连接断开)
SIGINT 2 Term 用户发送INTR字符(Ctrl+C)触发
SIGQUIT 3 Core 用户发送QUIT字符(Ctrl+/)触发
SIGILL 4 Core 非法指令(程序错误、试图执行数据段、栈溢出等)
SIGABRT 6 Core 调用abort函数触发
SIGFPE 8 Core 算术运行错误(浮点运算错误、除数为零等)
SIGKILL 9 Term 无条件结束程序(不能被捕获、阻塞或忽略)
SIGSEGV 11 Core 无效内存引用(试图访问不属于自己的内存空间、对只读内存空间进行写操作)
SIGPIPE 13 Term 消息管道损坏(FIFO/Socket通信时 管道未打开而进行写操作)
SIGALRM 14 Term 时钟定时信号
SIGTERM 15 Term 结束程序(可以被捕获、阻塞或忽略)
SIGUSR1 30,10,16 Term 用户保留
SIGUSR2 31,12,17 Term 用户保留
SIGCHLD 20,17,18 Ign 子进程结束(由父进程接收)
SIGCONT 19,18,25 Cont 继续执行已经停止的进程(不能被阻塞)
SIGSTOP 17,19,23 Stop 停止进程(不能被捕获、阻塞或忽略)
SIGTSTP 18,20,24 Stop 停止进程(可以被捕获、阻塞或忽略)
SIGTTIN 21,21,26 Stop 后台程序从终端中读取数据时触发
SIGTTOU 22,22,27 Stop 后台程序向终端中写数据时触发
在SUSv2和POSIX.1-2001标准中的信号列表:
信号 值 动作 说明
SIGTRAP 5 Core Trap指令触发(如断点 在调试器中使用)
SIGBUS 0,7,10 Core 非法地址(内存地址对齐错误)
SIGPOLL Term Pollable event (Sys V). Synonym for SIGIO
SIGPROF 27,27,29 Term 性能时钟信号(包含系统调用时间和进程占用CPU的时间)
SIGSYS 12,31,12 Core 无效的系统调用(SVr4)
SIGURG 16,23,21 Ign 有紧急数据到达Socket(4.2BSD)
SIGVTALRM 26,26,28 Term 虚拟时钟信号(进程占用CPU的时间)(4.2BSD)
SIGXCPU 24,24,30 Core 超过CPU时间资源限制(4.2BSD)
SIGXFSZ 25,25,31 Core 超过文件大小资源限制(4.2BSD)
尊贵的董事大人
英文标题不为空时 视为本栏投稿
需要关键字 描述 英文标题