作者:ppoujjh | 来源:互联网 | 2023-09-12 12:04
Go语言实战:API服务器(4)配置文件读取及连接数据库|小册免费学-读取配置文件主函数中增加配置初始化入口先导入viper包在main函数中增加了config.Init(
读取配置文件
主函数中增加配置初始化入口
- 先导入viper包
- 在 main 函数中增加了 config.Init(*cfg) 调用,用来初始化配置,cfg 变量值从命令行 flag 传入,可以传值,比如 ./apiserver -c config.yaml,也可以为空,如果为空会默认读取 conf/config.yaml。
- 将相应的配置改成从配置文件读取,例如程序的端口号,ip地址,运行模式
import (
...
"github.com/spf13/pflag"
"github.com/spf13/viper"
"log"
)
var (
cfg = pflag.StringP("config", "c", "", "apiserver config file path.")
)
func main() {
pflag.Parse()
if err:=config.Init(*cfg) ;err != nil {
panic(err)
}
g := gin.New()
gin.SetMode(viper.GetString("runmode"))
middlewares := []gin.HandlerFunc{}
router.Load(
g,
middlewares...,
)
go func() {
if err := pingServer(); err != nil {
log.Fatal("The router has no response, or it might took too long to start up.", err)
}
log.Print("The router has been deployed successfully.")
}()
log.Printf("Start to listening the incoming requests on http address: %s", viper.GetString("addr"))
log.Printf(http.ListenAndServe(viper.GetString("addr"), g).Error())
}
解析配置
- func Init(cfg string) 如果cfg不为空,加载指定配置文件,否则加载默认配置文件
- func (c *Config) watchConfig 通过该函数的 viper 设置,可以使 viper 监控配置文件变更,如有变更则热更新程序。所谓热更新是指:可以不重启 API 进程,使 API 加载最新配置项的值。
package config
import (
"log"
"strings"
"github.com/fsnotify/fsnotify"
"github.com/spf13/viper"
)
type Config struct {
Name string
}
func Init(cfg string) error {
c := Config {
Name: cfg,
}
if err := c.initConfig(); err != nil {
return err
}
c.watchConfig()
return nil
}
func (c *Config) initConfig() error {
if c.Name != "" {
viper.SetConfigFile(c.Name)
} else {
viper.AddConfigPath("conf")
viper.SetConfigName("config")
}
viper.SetConfigType("yaml")
viper.AutomaticEnv()
viper.SetEnvPrefix("APISERVER")
replacer := strings.NewReplacer(".", "_")
viper.SetEnvKeyReplacer(replacer)
if err := viper.ReadInConfig(); err != nil {
return err
}
return nil
}
func (c *Config) watchConfig() {
viper.WatchConfig()
viper.OnConfigChange(func(e fsnotify.Event) {
log.Printf("Config file changed: %s", e.Name)
})
}
数据库连接
ORM框架
apiserver 用的 ORM 是 GitHub 上 star 数最多的 gorm,相较于其他 ORM,它用起来更方便,更稳定,社区也更活跃。
建立数据连接
1.先配置文件中,配置数据库相关参数
db:
name: db_apiserver
addr: 127.0.0.1:3306
username: root
password: root
docker_db:
name: db_apiserver
addr: 127.0.0.1:3306
username: root
password: root
- 创建数据库连接结构体,并且初始化连接
type Database struct {
Self *gorm.DB
Docker *gorm.DB
}
func (db *Database) Init() {
DB = &Database{
Self: GetSelfDB(),
Docker: GetDockerDB(),
}
}
3.根据用户名密码等参数,打开连接
func openDB(username,password,addr,name string) *gorm.DB {
config :=fmt.Sprintf("%s:%s@tcp(%s)/%s?charset=utf8&parseTime=%t&loc=%s",
username,
password,
addr,
name,
true,
"Local")
db, err := gorm.Open("mysql", config)
if err!=nil{
log.Printf("Database connection failed. Database name: %s", name)
}
setupDB(db)
return db
}