Go中级之手把手教你开发一个简易的个人博客网站(二)项目配置独立化

前言

本文是记录的是"Go语言之手把手教你开发一个简易的个人博客网站(二·)"

此文是个人学习归纳的记录,腾讯云独家发布,未经允许,严禁转载,如有不对, 还望斧正, 感谢!

上一篇主要是记录了项目的基本架构和数据库的相关链接操作,本篇主要记录网站相关配置的抽离。

项目配置管理工具 Viper 基本用法

本项目使用go语言里面很流行的一个项目配置管理工具 Viper,目前有24.8k的start了

github地址:https://github.com/spf13/viper

Viper支持多种格式,如JSON、YAML、TOML等。以下是使用Viper的简单教程:

  • 安装Viper:

首先,需要安装Viper库。在goland中运行以下命令:

代码语言:shell
复制
   go get github.com/spf13/viper
  • 导入Viper:

在项目中,导入Viper库:

代码语言:go
复制
  import "github.com/spf13/viper"
  • 初始化Viper:

在使用Viper之前,需要对其进行初始化。可以使用以下代码初始化Viper:

代码语言:go
复制
  func init() {
       viper.SetConfigType("yaml") // 设置配置文件类型,这里是YAML
       viper.SetConfigName("config") // 设置配置文件名,这里是config.yaml
       viper.AddConfigPath(".") // 设置配置文件路径,这里是当前目录
       err := viper.ReadInConfig() // 读取配置文件
       if err != nil {
           panic(fmt.Errorf("Fatal error config file: %s", err))
       }
   }

这段代码将读取当前目录下的config.yaml文件。可以根据需要更改配置文件类型和名称。

  • 读取配置

在配置文件中,要使用键值对来存储配置信息。例如,在YAML文件中:

代码语言:yaml
复制
   database:
     host: localhost
     port: 5432
     name: mydb
     user: myuser
     password: mypassword

要读取这些配置,可以使用以下代码:

代码语言:go
复制
   func main() {
       dbHost := viper.GetString("database.host")
       dbPort := viper.GetInt("database.port")
       dbName := viper.GetString("database.name")
       dbUser := viper.GetString("database.user")
       dbPassword := viper.GetString("database.password")
   fmt.Printf("Database host: %s\n", dbHost)
   fmt.Printf("Database port: %d\n", dbPort)
   fmt.Printf("Database name: %s\n", dbName)
   fmt.Printf("Database user: %s\n", dbUser)
   fmt.Printf("Database password: %s\n", dbPassword)

}

这段代码将读取配置文件中的数据库配置信息,并将其打印到控制台。

  • 监听配置更改

Viper支持监听配置文件的更改,并自动重新加载配置。要实现这一功能,可以使用以下代码:

代码语言:go
复制
   func main() {
viper.WatchConfig()
viper.OnConfigChange(func(e fsnotify.Event) {
fmt.Println("Config file changed:", e.Name)
})

   // 在这里添加其他代码,例如读取配置并启动应用程序

}

这段代码将监听配置文件的更改,并在配置文件发生更改时打印一条消息。

详细用法,可以参考官方文档,我前面贴的了。

Viper在博客网站中的使用

首先先在项目目录下面,新建一个configs的文件夹,文件夹下面建一个config.yaml文件,然后写入你需要抽离出来的配置,按照现在的进度的话,目前我们需要记录的配置,首先就是gin框架的相关配置,然后就是数据库的相关配置。

代码语言:yaml
复制
Server:
RunMode: debug # 运行模式
HttpPort: 9090 # HTTP端口

Database:
MongodbHost: 127.0.0.1 #主机
MongodbPort: 27017 # 数据库端口
Mongodb_db: myblogmongodb # 数据库名称

然后我们就要结构化我们的这两个配置。

在pkg里面新建一个setting.go ,然后里面创建和config.yaml文件对应的结构体,后面将相关配置映射到结构体里面。

代码如下

代码语言:go
复制
package setting

import "time"

// ServerSetting 服务器配置
type ServerSetting struct {
RunMode string json:"runmode" // 运行模式
HttpPort string json:"httpport" // HTTP端口
}

// DatabaseSetting 数据库配置
type DatabaseSetting struct {
MongodbHost string // 数据库地址
MongodbPort string // 数据库端口
Mongodb_db string // 数据库名称
}

然后我们继续在后面完成viper的实例化和封装相关配置的读取操作。

键入如下代码

代码语言:go
复制
type Setting struct {
vp *viper.Viper
}

// NewSetting 实例化配置
func NewSetting() (*Setting, error) {
vp := viper.New()
vp.SetConfigName("config") //配置文件名
vp.AddConfigPath("configs/") // 路径
vp.SetConfigType("yaml") // 格式
if err := vp.ReadInConfig(); err != nil {
return nil, err
}
return &Setting{vp: vp}, nil
}

// ReadSection 读取配置
func (s *Setting) ReadSection(key string, value interface{}) error {
err := s.vp.UnmarshalKey(key, value)
if err != nil {
return err
}
return nil
}

接下来,我们把相关配置进行全局化声明,我们在global里面新建一个settings.go文件

代码语言:go
复制
var (
ServerSetting *setting.ServerSetting // 服务器配置实例
DatabaseSetting *setting.DatabaseSetting // 数据库配置实例
)

此时的话,其实这两个实例还只是空的,数据没有映射进去,接下来我们到main.go里面进行相关配置的初始化,键入以下代码

代码语言:go
复制
// 初始化配置信息
func setupSetting() error {
// 加载配置文件,这个函数是用来初始化的,前面定义了
setting, err := setting.NewSetting()
if err != nil {
return err
}
// 读取配置信息
if err := setting.ReadSection("Server", &global.ServerSetting); err != nil {
return err
}
if err := setting.ReadSection("Database", &global.DatabaseSetting); err != nil {
return err
}
return nil
}

然后在main.go里面的init函数里面,调用上面的函数,实际的数据的值,就会映射到global的全局变量里面了。

然后你在数据库配置文件和gin框架启动文件里面,调用全局变量,那全局变量里面的值替换掉实际的数据就行了,db.go的操作如下

代码语言:go
复制
// Client 定义一个全局变量,存储连接了数据库之后的句柄
var Client *mongo.Client

// 将那个配置信息直接传入
func MongodbJoin(databaseSetting *setting.DatabaseSetting) error {
// 连接到MongoDB
//clientOptions := options.Client().ApplyURI("mongodb://localhost")
clientOptions := options.Client().ApplyURI("mongodb://" + databaseSetting.MongodbHost + ":" + databaseSetting.MongodbPort)

// 使用连接选项连接到MongoDB
var err error
Client, err = mongo.Connect(context.Background(), clientOptions)
if err != nil {
	return fmt.Errorf("数据库连接失败:%v", err)
}

// 确保在最后关闭链接
err = Client.Disconnect(context.Background())
if err != nil {
	return fmt.Errorf("无法断开与Mongodb数据库的连接:%v", err)
}

return nil

}

还有就是,在main.go里面修改数据库的启动文件的信息,传入数据库的配置。

项目配置独立化的优势

  • 降低耦合度:将配置信息与代码分离,可以降低代码的复杂度和耦合度。这使得代码更加易于理解和维护。
  • 提高可维护性:将配置信息与代码分离,可以使得配置信息的修改不需要修改代码。这使得项目的配置管理更加灵活,并且可以降低代码出错的风险。
  • 便于部署:将配置信息与代码分离,可以使得项目在不同的环境中部署更加方便。例如,在开发环境和生产环境中,可以使用不同的配置文件,以适应不同的环境需求。
  • 便于版本控制:将配置信息与代码分离,可以使得项目的版本控制更加简单。例如,可以使用Git等版本控制工具来管理配置文件,以便于跟踪配置文件的变更历史。

本次实践参考《go语言编程之旅》的设计思路。

我正在参与2023腾讯技术创作特训营第四期有奖征文,快来和我瓜分大奖!