读取配置文件
主函数中增加配置初始化入口
- 先导入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)
}
// Create the Gin engine.
g := gin.New()
gin.SetMode(viper.GetString("runmode"))
middlewares := []gin.HandlerFunc{}
// Routes.
router.Load(
// Cores.
g,
// Middlwares.
middlewares...,
)
// Ping the server to make sure the router is working.
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") // 设置配置文件格式为YAML
viper.AutomaticEnv() // 读取匹配的环境变量
viper.SetEnvPrefix("APISERVER") // 读取环境变量的前缀为APISERVER
replacer := strings.NewReplacer(".", "_")
viper.SetEnvKeyReplacer(replacer)
if err := viper.ReadInConfig(); err != nil { // viper解析配置文件
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,
//"Asia/Shanghai"),
"Local")
db, err := gorm.Open("mysql", config)
if err!=nil{
log.Printf("Database connection failed. Database name: %s", name)
}
setupDB(db)
return db
}
复制代码
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END