上一篇博客我们介绍了项目布局, 这一篇介绍关于配置文件
目录
这次我们选用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为正确的值
下一篇介绍关于数据库的配置
发表回复