Viper使用简介-基于Tendermint

本文介绍了Tendermint如何利用Viper进行配置管理。Viper是一个全功能的Go语言配置解决方案,允许设置配置文件名称、路径,并能自动识别多种后缀的配置文件。在使用过程中,可以通过SetConfigName和AddConfigPath添加配置文件信息,ReadInConfig读取内容。Viper提供GetString、GetBool等方法读取单个变量,以及通过Unmarshal方法将配置信息映射到结构体。在结构体映射时,需使用'mapstructure:"seeds"'注解帮助Viper找到对应的变量。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Tendermint需要配置一些属性的时候是在config.toml中配置的,刚开始没看明白toml配置文件是如何生效的,深入了解了一下做个记录。

原来tnedermint使用了viper(ˈvaɪpə(r),现在看到i都得确认下发什么音)开源项目,那么viper是什么呢

看下github的解释:https://github.com/spf13/viper

Viper is a complete configuration solution for Go applications including 12-Factor apps. It is designed to work within an application, and can handle all types of configuration needs and formats. It supports:

setting defaults
reading from JSON, TOML, YAML, HCL, and Java properties config files
live watching and re-reading of config files (optional)
reading from environment variables
reading from remote config systems (etcd or Consul), and watching changes
reading from command line flags
reading from buffer
setting explicit values
Viper can be thought of as a registry for all of your applications configuration needs.

(csdn改版了啊,这个框可以再编辑了,以前没法编辑,需要更改里面的代码还需要删除重新添加才可以,赞一个)

意思就是Viper是一个基于Go语言的全功能的配置解决方案。就是如果你的程序需要一些配置属性,它都可以做到。

这么来看viper其实就是类似一个库的功能了,那么对于库的使用我们还是比较熟悉的,那么就从使用库的角度来介绍下Viper是如何使用的吧,然后再找机会深入分析

(csdn有bug啊,写完了之后直接点了发布博客,有的内容没有保存,导致有丢失。可能需要先点击保存修改才可以。本来文章都写完了发现没有了,心都拔凉拔凉的,稍微补一点吧)

配置文件

// Bind all flags and read the config into viper
func bindFlagsLoadViper(cmd *cobra.Command, args []string) error {
	// cmd.Flags() includes flags from this command and all persistent flags from the parent
	if err := viper.BindPFlags(cmd.Flags()); err != nil {
		return err
	}

	homeDir := viper.GetString(HomeFlag)
	viper.Set(HomeFlag, homeDir)
	viper.SetConfigName("config") // name of config file (without extension)
	viper.AddConfigPath(homeDir)  // search root directory

	// If a config file is found, read it in.
	if err := viper.ReadInConfig(); err == nil {
		// stderr, so if we redirect output to json file, this doesn't appear
		// fmt.Fprintln(os.Stderr, "Using config file:", viper.ConfigFileUsed())
	} else if _, ok := err.(viper.ConfigFileNotFoundError); !ok {
		// we ignore not found error, only parse error
		// stderr, so if we redirect output to json file, this doesn't appear
		fmt.Fprintf(os.Stderr, "%#v", err)
	}
	return nil
}

 1 viper.SetConfigName 设置配置文件的名字

2 viper.AddConfigPath 设置配置文件的路径,为什么是add不是set呢,它的实现是append,就是它可以支持多目录搜索

3 viper.ReadInConfig 读取配置文件的内容然后放在viper.config内

只有path和名字就可以找到文件吗?后缀名呢?viper会查找一些内置支持的后缀

// SupportedExts are universally supported extensions.
var SupportedExts = []string{"json", "toml", "yaml", "yml", "properties", "props", "prop", "hcl"}

读取内容

单个变量的读取比较简单,直接GetX(key)就行了,比如GetString,GetBool等

viper.GetString("encoding")

viper还支持结构体读取,比如Config结构体

func ParseConfig() (*UltronConfig, error) {
	conf := DefaultConfig()
	err := viper.Unmarshal(&conf)
	if err != nil {
		return nil, err
	}
	conf.TMConfig.SetRoot(conf.BaseConfig.RootDir)
	ensureRoot(conf.BaseConfig.RootDir)

	return conf, err
}

 调用viper.Unmarshal(&conf)填充conf结构的内容

type P2PConfig struct {
	RootDir string `mapstructure:"home"`

	// Address to listen for incoming connections
	ListenAddress string `mapstructure:"laddr"`

	// Comma separated list of seed nodes to connect to
	Seeds string `mapstructure:"seeds"`

	// Skip UPNP port forwarding
	SkipUPNP bool `mapstructure:"skip_upnp"`

	// Path to address book
	AddrBook string `mapstructure:"addr_book_file"`

	// Set true for strict address routability rules
	AddrBookStrict bool `mapstructure:"addr_book_strict"`

	// Set true to enable the peer-exchange reactor
	PexReactor bool `mapstructure:"pex"`

	// Maximum number of peers to connect to
	MaxNumPeers int `mapstructure:"max_num_peers"`

	// Time to wait before flushing messages out on the connection, in ms
	FlushThrottleTimeout int `mapstructure:"flush_throttle_timeout"`

	// Maximum size of a message packet payload, in bytes
	MaxMsgPacketPayloadSize int `mapstructure:"max_msg_packet_payload_size"`

	// Rate at which packets can be sent, in bytes/second
	SendRate int64 `mapstructure:"send_rate"`

	// Rate at which packets can be received, in bytes/second
	RecvRate int64 `mapstructure:"recv_rate"`
}

 这个是config.toml中的p2p

[p2p]
laddr = "tcp://0.0.0.0:46656"
seeds = "172.29.18.158:46656"

两个是有对应关系的。在代码中需要写 'mapstructure:"seeds"',然后viper读取的时候会根据这个规则对应到具体的变量上

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值