1

我的应用程序正在使用 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
}

调用函数时我面临两个问题:

  1. 许多卷曲连接正在建立并悬而未决。
  2. 重负载会导致 goroutine/线程耗尽。
  3. 脚本进程不会终止。

你能帮我用更好的方法来实现同样的目标吗?提前致谢。

4

0 回答 0