上一篇博客我们介绍了项目布局, 这一篇介绍关于配置文件
目录
这次我们选用yaml来作为配置文件的格式
在项目的config目录下, 新建一个config.yaml文件
Server: RunMode: debug HttpPort: 8000 ReadTimeout: 60 WriteTimeout: 60 App: LogSavePath: ./logs/ LogFileName: app LogFileExt: .log TokenExpire: 12 Secert: asdfghjjkuytttrrr FedidTokenHeaderKey: xxxx FedidTokenHeaderType: xx FedidTokenUrl: xxxx FedidUserInfoUrl: xxx Database: Username: xx Password: x. Host: x.x.x.x DBName: x Charset: utf8mb4 ParseTime: True MaxIdleCoons: 10 MaxOpenConns: 30
Server段
我们定义了一些关于gin的配置, 比如运行模式, 在开发中, 我们使用debug, 在生产环境时, 使用release, 其他比如监听端口, 超时时间等
App段
我们定义了一些应用相关的配置, 比如日志保存的路径, 名字, 后缀, 以及token的秘钥, 过期时间, Fedid相关的配置是我们公司有统一认证的api, 所以我们这边只需要调用那边的api , 获取用户信息, 然后在我们的数据库中创建用户, 进行权限认证
Database段
定义了数据库相关的配置, 账号,密码,主机名, 库名, 字符集, 空闲连接数, 最大连接数等
接着我们写关于解析配置文件的代码, 在config文件夹在新建一个setting文件夹, 再新建两个文件
section.go
package setting
import "time"
type ServerSettingS struct {
RunMode string
HttpPort string
ReadTimeout time.Duration
WriteTimeout time.Duration
}
type AppSettingS struct {
LogSavePath string
LogFileName string
LogFileExt string
Secert string
TokenExpire time.Duration
CallBackUrl string
FedidTokenHeaderKey string
FedidTokenHeaderType string
FedidTokenUrl string
FedidUserInfoUrl string
SecertByte []byte
}
type DatabaseSettingS struct {
UserName string
Password string
Host string
DBName string
Charset string
ParseTime bool
MaxIdleConns int
MaxOpenConns int
}
func (s *Setting) ReadSection(k string, v interface{}) error {
err := s.vp.UnmarshalKey(k, v)
if err != nil {
return err
}
return nil
}
setting.go
package setting
import "github.com/spf13/viper"
type Setting struct {
vp *viper.Viper
}
func NewSetting() (*Setting, error) {
vp := viper.New()
vp.SetConfigName("config")
vp.AddConfigPath("config/")
vp.SetConfigType("yaml")
err := vp.ReadInConfig()
if err != nil {
return nil, err
}
return &Setting{vp}, nil
}
我们选择了viper作为解析配置文件的库
在setting的go中, 定义了NewSetting方法, 里面读取了配置文件, 返回了Setting结构体的实例
在section.go中, 我们定义了3个结构体, 分别对应配置文件的三段, 它们的属性分别对应了配置文件中的单项配置. ReadSection方法把viper读取到的值返回给对应的结构体
接着我们在global文件夹下, 新建setting.go文件
package global import ( "gin_study/config/setting" ) var ( ServerSetting *setting.ServerSettingS AppSetting *setting.AppSettingS DatabaseSetting *setting.DatabaseSettingS )
修改一下main.go的内容
package main
import (
"fmt"
"gin_study/config/setting"
"gin_study/global"
"log"
"time"
"github.com/gin-gonic/gin"
)
func setupSetting() error {
setting, err := setting.NewSetting()
if err != nil {
return err
}
err = setting.ReadSection("Server", &global.ServerSetting)
if err != nil {
return err
}
err = setting.ReadSection("App", &global.AppSetting)
if err != nil {
return err
}
err = setting.ReadSection("Database", &global.DatabaseSetting)
if err != nil {
return err
}
global.ServerSetting.ReadTimeout *= time.Second
global.ServerSetting.WriteTimeout *= time.Second
global.AppSetting.TokenExpire *= time.Hour
global.AppSetting.SecertByte = []byte(global.AppSetting.Secert)
return nil
}
func init() {
err := setupSetting()
if err != nil {
log.Fatalf("初始化配置文件异常: %v", err)
}
}
func main() {
fmt.Println(global.ServerSetting.RunMode)
gin.SetMode(global.ServerSetting.RunMode)
r := gin.Default()
r.GET("/ping", func(ctx *gin.Context) {
ctx.JSON(200, gin.H{"message": "pong"})
})
r.Run()
}
定义了一个setupSetting函数, 分别读取不同的section, 赋值给global中对应的结构体, 然后在init函数中, 读取配置, 这样我们在其他所有包, 就可以直接调用global.xxSetting.xx去获取配置文件中的值, 非常方便

可以看到我们运行时, 可以打印出global.ServerSetting.RunMode为正确的值
下一篇介绍关于数据库的配置
发表回复