热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Go语言实战:API服务器(4)配置文件读取及连接数据库|小册免费学

Go语言实战:API服务器(4)配置文件读取及连接数据库|小册免费学-读取配置文件主函数中增加配置初始化入口先导入viper包在main函数中增加了config.Init(

读取配置文件

主函数中增加配置初始化入口

  1. 先导入viper包
  2. 在 main 函数中增加了 config.Init(*cfg) 调用,用来初始化配置,cfg 变量值从命令行 flag 传入,可以传值,比如 ./apiserver -c config.yaml,也可以为空,如果为空会默认读取 conf/config.yaml。
  3. 将相应的配置改成从配置文件读取,例如程序的端口号,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())
}

解析配置

  1. func Init(cfg string) 如果cfg不为空,加载指定配置文件,否则加载默认配置文件
  2. 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
  1. 创建数据库连接结构体,并且初始化连接
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
}

推荐阅读
author-avatar
ppoujjh
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有