前言
本文是记录的是"Go语言之手把手教你开发一个简易的个人博客网站(二·)"
此文是个人学习归纳的记录,腾讯云独家发布,未经允许,严禁转载,如有不对, 还望斧正, 感谢!
上一篇主要是记录了项目的基本架构和数据库的相关链接操作,本篇主要记录网站相关配置的抽离。
项目配置管理工具 Viper 基本用法
本项目使用go语言里面很流行的一个项目配置管理工具 Viper,目前有24.8k的start了
github地址:https://github.com/spf13/viper
Viper支持多种格式,如JSON、YAML、TOML等。以下是使用Viper的简单教程:
- 安装Viper:
首先,需要安装Viper库。在goland中运行以下命令:
go get github.com/spf13/viper
- 导入Viper:
在项目中,导入Viper库:
import "github.com/spf13/viper"
- 初始化Viper:
在使用Viper之前,需要对其进行初始化。可以使用以下代码初始化Viper:
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文件中:
database:
host: localhost
port: 5432
name: mydb
user: myuser
password: mypassword
要读取这些配置,可以使用以下代码:
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支持监听配置文件的更改,并自动重新加载配置。要实现这一功能,可以使用以下代码:
func main() {
viper.WatchConfig()
viper.OnConfigChange(func(e fsnotify.Event) {
fmt.Println("Config file changed:", e.Name)
})// 在这里添加其他代码,例如读取配置并启动应用程序
}
这段代码将监听配置文件的更改,并在配置文件发生更改时打印一条消息。
详细用法,可以参考官方文档,我前面贴的了。
Viper在博客网站中的使用
首先先在项目目录下面,新建一个configs的文件夹,文件夹下面建一个config.yaml文件,然后写入你需要抽离出来的配置,按照现在的进度的话,目前我们需要记录的配置,首先就是gin框架的相关配置,然后就是数据库的相关配置。
Server:
RunMode: debug # 运行模式
HttpPort: 9090 # HTTP端口
Database:
MongodbHost: 127.0.0.1 #主机
MongodbPort: 27017 # 数据库端口
Mongodb_db: myblogmongodb # 数据库名称
然后我们就要结构化我们的这两个配置。
在pkg里面新建一个setting.go ,然后里面创建和config.yaml文件对应的结构体,后面将相关配置映射到结构体里面。
代码如下
package setting
import "time"
// ServerSetting 服务器配置
type ServerSetting struct {
RunMode stringjson:"runmode"
// 运行模式
HttpPort stringjson:"httpport"
// HTTP端口
}
// DatabaseSetting 数据库配置
type DatabaseSetting struct {
MongodbHost string // 数据库地址
MongodbPort string // 数据库端口
Mongodb_db string // 数据库名称
}
然后我们继续在后面完成viper的实例化和封装相关配置的读取操作。
键入如下代码
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文件
var (
ServerSetting *setting.ServerSetting // 服务器配置实例
DatabaseSetting *setting.DatabaseSetting // 数据库配置实例
)
此时的话,其实这两个实例还只是空的,数据没有映射进去,接下来我们到main.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的操作如下
// 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腾讯技术创作特训营第四期有奖征文,快来和我瓜分大奖!