我的应用程序正在使用 redigo 客户端库与 redis 服务器建立 TCP 连接。我想在运行时更改redis的密码,并希望redigo库在后续连接中使用新密码。(在 redis 池中)
我已经通过以下方式定义了我的 redis-pool 对象来实现这一点。
return &redis.Pool{
MaxIdle: 5,
MaxActive: 1000,
IdleTimeout: time.Minute,
Dial: func() (redis.Conn, error) {
cErr = getRedisPassword()
if cErr != nil {
return nil, cErr
}
if gRedisAuthPassword != "" {
opts[1] = redis.DialPassword(gRedisAuthPassword)
}
return redis.Dial("tcp", addr, opts...)
},
TestOnBorrow: func(c redis.Conn, t time.Time) error {
_, err := c.Do("PING")
cErr = err
return err
},
}, nil
调用函数时的选项是:
cluster := &redisc.Cluster{
StartupNodes: nodesInfo,
DialOptions: []redis.DialOption{redis.DialConnectTimeout(5 * time.Second), redis.DialPassword(gRedisAuthPassword)},
CreatePool: createPool,
getRedisPassword 函数如下所示:该函数确实调用了一个脚本,该脚本获取了 redis 集群的最新密码。
func getRedisPassword() error {
var cErr error
cErr = nil
if ssFlag == "YES" {
cmd := exec.Command("/bin/bash", "-c", "/opt/lte/etc/utility/fetch_redisPassword.sh")
pass, err := cmd.CombinedOutput()
gRedisAuthPassword = string(pass)
cErr = err
// Wait for the process to finish or kill it after a timeout (whichever happens first):
done := make(chan error, 1)
go func() {
done <- cmd.Wait()
}()
select {
case <-time.After(3 * time.Second):
if err := cmd.Process.Kill(); err != nil {
fmt.Println("error:", err)
}
case err := <-done:
if err != nil {
fmt.Println("error:", err)
}
}
} else {
return cErr
}
if cErr != nil || gRedisAuthPassword == "null" || gRedisAuthPassword == "" {
//print log
cErr = ErrDbConnFailed
}
return cErr
}
调用函数时我面临两个问题:
- 许多卷曲连接正在建立并悬而未决。
- 重负载会导致 goroutine/线程耗尽。
- 脚本进程不会终止。
你能帮我用更好的方法来实现同样的目标吗?提前致谢。