| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128 |
- package config
- import (
- "bufio"
- "io"
- "os"
- "reflect"
- "strconv"
- "strings"
- "github.com/runningwater/go-redis/lib/logger"
- )
- // ServerProperties 定义了服务器的全局配置属性
- type ServerProperties struct {
- // Bind 服务器绑定的IP地址
- Bind string `cfg:"bind"`
- // Port 服务器监听的端口号
- Port int `cfg:"port"`
- // AppendOnly 是否启用AOF持久化模式
- AppendOnly bool `cfg:"appendOnly"`
- // AppendFilename AOF文件名
- AppendFilename string `cfg:"appendFilename"`
- // MaxClients 最大客户端连接数
- MaxClients int `cfg:"maxclients"`
- // RequirePass 访问服务器所需的密码
- RequirePass string `cfg:"requirepass"`
- // Databases 数据库数量
- Databases int `cfg:"databases"`
- // Peers 集群中其他节点地址列表
- Peers []string `cfg:"peers"`
- // Self 当前节点在集群中的地址
- Self string `cfg:"self"`
- }
- // Properties 持有全局配置属性的实例
- var Properties *ServerProperties
- func init() {
- // 默认配置
- Properties = &ServerProperties{
- Bind: "127.0.0.1",
- Port: 6379,
- AppendOnly: false,
- }
- }
- // parse 解析配置文件,将配置项映射到ServerProperties结构体中
- func parse(src io.Reader) *ServerProperties {
- config := &ServerProperties{}
- // 读取配置文件
- rawMap := make(map[string]string)
- scanner := bufio.NewScanner(src)
- for scanner.Scan() {
- line := scanner.Text()
- // 跳过注释行(以#开头的行)
- if len(line) > 0 && line[0] == '#' {
- continue
- }
- // 查找第一个空格位置,分离键和值
- pivot := strings.IndexAny(line, " ")
- if pivot > 0 && pivot < len(line)-1 { // 找到分隔符
- key := line[0:pivot]
- value := strings.Trim(line[pivot+1:], " ")
- rawMap[strings.ToLower(key)] = value
- }
- }
- if err := scanner.Err(); err != nil {
- logger.Fatal(err)
- }
- // 使用反射解析配置格式
- t := reflect.TypeOf(config)
- v := reflect.ValueOf(config)
- n := t.Elem().NumField()
- for i := 0; i < n; i++ {
- field := t.Elem().Field(i)
- fieldVal := v.Elem().Field(i)
- // 获取cfg标签作为配置键名,如果没有则使用字段名
- key, ok := field.Tag.Lookup("cfg")
- if !ok {
- key = field.Name
- }
- value, ok := rawMap[strings.ToLower(key)]
- if ok {
- // 根据字段类型填充配置值
- switch field.Type.Kind() {
- case reflect.String:
- fieldVal.SetString(value)
- case reflect.Int:
- intValue, err := strconv.ParseInt(value, 10, 64)
- if err == nil {
- fieldVal.SetInt(intValue)
- }
- case reflect.Bool:
- boolValue := value == "yes"
- fieldVal.SetBool(boolValue)
- case reflect.Slice:
- if field.Type.Elem().Kind() == reflect.String {
- slice := strings.Split(value, ",")
- fieldVal.Set(reflect.ValueOf(slice))
- }
- default:
- // 未处理的类型
- panic("unhandled default case")
- }
- }
- }
- return config
- }
- // SetupConfig 读取配置文件并将属性存储到Properties变量中
- func SetupConfig(configFilename string) {
- file, err := os.Open(configFilename)
- if err != nil {
- panic(err)
- }
- defer func() {
- closeErr := file.Close()
- if closeErr != nil {
- panic(closeErr)
- }
- }()
- Properties = parse(file)
- }
|