Skip to content

介绍

配置文件管理库 viper 它支持这些格式:

  • JSON
  • TOML
  • YAML
  • INI
  • envfile

并且支持从远程(etcd/consul)读取/监控配置文件变化

安装

go
go get github.com/spf13/viper

读取/设置配置选项

go
package main

import (
	"log"

	"github.com/gofiber/fiber/v3"
	"github.com/spf13/viper"
)

func main() {
	app := fiber.New()

	config := viper.New()                   // 获取实例

	// 设置值
	config.SetDefault("mysql.port", "3306") // 低优先级
	config.Set("mysql.port", "33060")       // 高优先级

	app.Get("/", func(c fiber.Ctx) error {
		// 获取值
		// mysqlPort := config.Get("mysql.port") // 33060
		mysqlPort := config.Get("MYSQL.PORT") // 注: 配置选项不区分大小写
		return c.JSON(fiber.Map{
			"mysqlPort": mysqlPort,
		})
	})

	if err := app.Listen(":3000"); err != nil {
		log.Fatal(err)
	}
}

将配置持久化

go
package main

import (
	"log"

	"github.com/gofiber/fiber/v3"
	"github.com/spf13/viper"
)

func main() {
	app := fiber.New()

	config := viper.New() // 获取实例

	// 写入配置文件
	app.Get("/save", func(c fiber.Ctx) error {
		// 设置值
		config.SetDefault("mysql.port", "3306") // 低优先级
		config.Set("mysql.port", "33060")       // 高优先级

		config.SetConfigType("json")        // 1.设置配置类型 json/yaml/toml/ini
		config.SetConfigFile("config.json") // 2.设置配置文件名称
		err := config.WriteConfig()         // 3.直接写入配置文件(config.json)
		if err != nil {
			return err
		}

		err2 := config.WriteConfigAs("config2.json") // 写入指定的配置文件(会覆盖写入)
		if err2 != nil {
			return err2
		}

		// 写入配置文件(如果cnofig3.json已经存在则
		// 抛出异常,而不是覆盖写入)
		err3 := config.SafeWriteConfigAs("config3.json")
		if err3 != nil {
			return err3
		}

		return c.JSON(fiber.Map{
			"msg": "success",
		})
	})

	// 读取配置文件
	app.Get("/read", func(c fiber.Ctx) error {
		config.SetConfigType("json")        // 1.设置配置类型 json/yaml/toml/ini
		config.SetConfigFile("config.json") // 2.设置配置文件名称

		// 增加配置文件扫描路
		config.AddConfigPath("/etc/appname")   // 1.找 /etc/appname/config.json
		config.AddConfigPath("$HOME/.appname") // 2.找 ~/.appname/config.json
		config.AddConfigPath(".")              // 3.找 ./config.json

		err := config.ReadInConfig()
		if err != nil {
			return err
		}

		settings := config.AllSettings()

		return c.JSON(fiber.Map{
			"config": settings, // 从文件中读取配置成功后,获取所有配置选项
		})
	})

	if err := app.Listen(":3000"); err != nil {
		log.Fatal(err)
	}
}

监听配置文件变化

go
package main

import (
	"fmt"
	"log"

	"github.com/fsnotify/fsnotify"
	"github.com/gofiber/fiber/v3"
	"github.com/spf13/viper"
)

func main() {
	app := fiber.New()

	config := viper.New() // 获取实例

	config.SetConfigType("json")
	config.SetConfigFile("config.json")

	config.WatchConfig()
	config.OnConfigChange(func(e fsnotify.Event) {
	  // 输出被修改的文件
		fmt.Println("config file changed:", e.Name)
	})

	// app.Get("/", func(c *fiber.Ctx) error {})

  // Listen 会阻塞主线程不退出, 此时只需要
  // 1. go run main.go
  // 2. 修改 config.json
  // 3. 观察控制台输出,如果 OnConfigChange 回调执行说明监听到了
	if err := app.Listen(":3000"); err != nil {
		log.Fatal(err)
	}
}

读取环境变量

go
package main

import (
	"log"
	"os"

	"github.com/gofiber/fiber/v3"
	"github.com/spf13/viper"
)

func main() {
	app := fiber.New()

	config := viper.New() // 获取实例

	// 设置环境变量
	os.Setenv("LOG_LEVEL", "debug")

	// 自动加载所有环境变量
	config.AutomaticEnv()

	app.Get("/env", func(c fiber.Ctx) error {

		settings := map[string]any{
			"log_level": config.Get("log_level"),
			"log_level2": os.Getenv("log_level"),
		}

		return c.JSON(settings)
	})

	if err := app.Listen(":3000"); err != nil {
		log.Fatal(err)
	}
}

Released under the MIT License.