Saki's 研究记录

Parsing a Redis connection string

字数统计: 344阅读时长: 1 min
2022/07/03

背景

最近在工作中需要访问redis,为了方便使用,将redis的地址、端口、密码等写到配置中读取。例如:

1
2
3
4
5
# redis configuration
redis:
db: 0
addr: 'redis-ip:10086'
password: '******'

这样配置是没问题的,但计划赶不上变化,当需求改成写个命令行工具来读访问 redis时,就用不上配置文件了。
redis的配置需要从命令行的参数传入,例如:

1
cmd subcmd --redis_addr 'redis-ip:10086' --redis_pwd '******' --redis_db 0

这样实现不仅不美观,而且使用起来因为参数太多变得麻烦。

解决

按照之前的开发经验,想起可以通过 redis url来合并 redis的多个配置项。redis url 的格式类似于:

redis://:password@hostname:port/db_number

详细细节请参考Redis URI and connection details
golang实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
// ParseRedisURL parse redis url (redis://user:pwd@host/db_number)
func ParseRedisURL(str string) (map[string]string, error) {
u, err := url.Parse(str)
if err != nil {
return map[string]string{}, err
}

if u.Scheme != `redis` && u.Scheme != `rediss` {
return map[string]string{}, fmt.Errorf("invalid scheme %s for %s", u.Scheme, str)
}

config := map[string]string{
`db_number`: strings.Trim(u.Path, "/"),
`host`: u.Host,
}

for k, v := range u.Query() {
config[k] = v[0]
}

user := u.User.Username()
if user != `` {
config[`user`] = user
}

pass, exists := u.User.Password()
if exists {
config[`pwd`] = pass
}

return config, nil
}

总结

只要思想不滑坡,办法总比困难多。

CATALOG
  1. 1. 背景
  2. 2. 解决
  3. 3. 总结