使用Viper管理配置文件,进行MySQL、Redis的初始化 | 青训营笔记

757 阅读2分钟

这是我参与「第三届青训营 -后端场」笔记创作活动的第2篇笔记。

使用Viper管理配置文件,进行MySQL、Redis的初始化

Viper是适用于Go应用程序的完整配置解决方案。它被设计用于在应用程序中工作,并且可以处理所有类型的配置需求和格式。

以MySQL、Redis的配置为例,把配置信息写入到config.yaml文件,项目启动时加载。

yaml文件

在项目目录下编写config.yaml文件

mysql:
  path: 127.0.0.1
  port: 3306
  config: charset=utf8&parseTime=True&loc=Local
  db-name: douyin
  username: root
  password: 123456
  max-idle-conns: 10
  max-open-conns: 100
redis:
  db: 0
  addr: xiaozhang.fit:6379
  password: "94264944htz"

配置信息对应的go文件

新建config目录,在config目录新建mysql.go、redis.go、config.go文件,存放对应的配置信息。

mysql.go

type Mysql struct {
	Path         string `mapstructure:"path" yaml:"path"`                     // 服务器地址
	Port         string `mapstructure:"port" yaml:"port"`                     // 端口
	Config       string `mapstructure:"config" yaml:"config"`                 // 高级配置
	Dbname       string `mapstructure:"db-name" yaml:"db-name"`               // 数据库名
	Username     string `mapstructure:"username" yaml:"username"`             // 数据库用户名
	Password     string `mapstructure:"password" yaml:"password"`             // 数据库密码
	MaxIdleConns int    `mapstructure:"max-idle-conns" yaml:"max-idle-conns"` // 空闲中的最大连接数
	MaxOpenConns int    `mapstructure:"max-open-conns" yaml:"max-open-conns"` // 打开到数据库的最大连接数
}

func (m *Mysql) Dsn() string {
	return m.Username + ":" + m.Password + "@tcp(" + m.Path + ":" + m.Port + ")/" + m.Dbname + "?" + m.Config
}

redis.go

type Redis struct {
	DB       int    `mapstructure:"db" yaml:"db"`             // redis的哪个数据库
	Addr     string `mapstructure:"addr" yaml:"addr"`         // 服务器地址:端口
	Password string `mapstructure:"password" yaml:"password"` // 密码
}

config.go

type Server struct {
	Mysql    Mysql    `mapstructure:"mysql" yaml:"mysql"`
	Redis    Redis    `mapstructure:"redis" yaml:"redis"`
}

全局配置对象

在 global 目录下新建 global.go 文件,用来存放全局信息,如全局配置。

package global

import (
	"github.com/RaymondCode/simple-demo/config"
	"github.com/go-redis/redis/v8"
	"gorm.io/gorm"
)

var (
	DB     *gorm.DB
	RD     *redis.Client
	CONFIG config.Server // 配置信息
)

项目初始化

新建 initialize 目录,编写 config.go、mysql.go、redis.go 分别进行配置信息、mysql、redis的初始化操作

config.go

首先利用 os.Getwd() 获取当前项目的路径,再通过配置文件路径、名称、类型信息,利用viper加载配置文件

package initialize

import (
	"fmt"
	"github.com/RaymondCode/simple-demo/global"
	"github.com/spf13/viper"
	"os"
)

// Read  ReadConfig
func Read(configName string, configPath string, configType string) *viper.Viper {
	v := viper.New()
	v.SetConfigName(configName) // 文件名
	v.AddConfigPath(configPath) // 文件路径
	v.SetConfigType(configType) // 文件类型
	err := v.ReadInConfig()
	if err != nil {
		panic(fmt.Errorf("Fatal error config file: %s \n", err))
	}
	//res := v.AllKeys()
	//log.Println("res = ", res)
	return v
}

// Config InitConfig
func Config() {
	path, err := os.Getwd()
	if err != nil {
		panic(err)
	}
    // 读取配置文件
	v := Read("config", path, "yaml")
    // unmarshals the config into a Struct
	if err := v.Unmarshal(&global.CONFIG); err != nil {
		fmt.Println(err)
	}
	// fmt.Println(global.CONFIG)
	// fmt.Println("---------------------------------")
}

mysql.go

利用 global.CONFIG 里面的MySQL配置信息进行MySQL的初始化操作,建立数据库连接

package initialize

import (
	"github.com/RaymondCode/simple-demo/global"
	"gorm.io/driver/mysql"
	"gorm.io/gorm"
	"gorm.io/gorm/logger"
)

func Mysql() {
	mysqlConfig := mysql.Config{
		DSN:                       global.CONFIG.Mysql.Dsn(), // DSN data source name
		DefaultStringSize:         191,                       // string 类型字段的默认长度
		SkipInitializeWithVersion: false,                     // 根据版本自动配置
	}
	var err error
	global.DB, err = gorm.Open(mysql.New(mysqlConfig),
		&gorm.Config{
			PrepareStmt:            true,
			SkipDefaultTransaction: true,
			Logger:                 logger.Default.LogMode(logger.Info),
		},
	)
	if err != nil {
		panic(err)
	} else {
		sqlDB, _ := global.DB.DB()
		sqlDB.SetMaxIdleConns(global.CONFIG.Mysql.MaxIdleConns)
		sqlDB.SetMaxOpenConns(global.CONFIG.Mysql.MaxOpenConns)
	}
}

redis.go

利用 global.CONFIG 里面的 Redis 配置信息进行Redis的初始化操作,建立连接

package initialize

import (
	"context"
	"fmt"
	"github.com/RaymondCode/simple-demo/global"
	"github.com/go-redis/redis/v8"
	"go.uber.org/zap"
)

func Redis() {
	redisCfg := global.CONFIG.Redis
	client := redis.NewClient(&redis.Options{
		Addr:     redisCfg.Addr,
		Password: redisCfg.Password, // no password set
		DB:       redisCfg.DB,       // use default DB
	})
	pong, err := client.Ping(context.Background()).Result()
	if err != nil {
		panic(err)
	} else {
		fmt.Println("redis connect ping reRDonse:", zap.String("pong", pong))
		global.RD = client // 保存到全局
	}
}

项目启动

启动之前进行相关初始化操作

package main

import (
   "github.com/RaymondCode/simple-demo/initialize"
   "github.com/gin-gonic/gin"
)

func main() {
   r := gin.Default()

   initialize.Config()
   initialize.Mysql()
   initialize.Redis()
   // initialize.Routers(r)

   r.Run() // listen and serve on 0.0.0.0:8080 (for windows "localhost:8080")
}