这是我参与「第三届青训营 -后端场」笔记创作活动的第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")
}