所以,我有必要连接到3台redis服务器。我创建了3个连接池,并初始化它们。 但redigo似乎只连接到单个redis服务器,虽然我使用不同的池获得连接。
使用redigo,这是我的代码
import (
"fmt"
"time"
"github.com/garyburd/redigo/redis"
)
var poolA *redis.Pool
var poolB *redis.Pool
var poolC *redis.Pool
func main() {
poolA = &redis.Pool{}
poolB = &redis.Pool{}
poolC = &redis.Pool{}
connections := []string{"localhost:6379", "localhost2:6379", "localhost3:6379"}
for k, v := range connections {
redisPool := &redis.Pool{
Dial: func() (redis.Conn, error) {
return redis.Dial("tcp", v)
},
TestOnBorrow: func(c redis.Conn, t time.Time) error {
if time.Since(t) < time.Minute {
return nil
}
_, err := c.Do("PING")
return err
},
IdleTimeout: time.Duration(10) * time.Second,
MaxActive: 100,
MaxIdle: 100 / 2,
Wait: true,
}
if k == 0 {
fmt.Println("poolA:", v)
poolA = redisPool
}
if k == 1 {
fmt.Println("poolB:", v)
poolB = redisPool
}
if k == 2 {
fmt.Println("poolC:", v)
poolC = redisPool
}
}
con := poolA.Get()
defer con.Close()
count, err := redis.Int(con.Do("SADD", "any:test", 3246))
if err != nil {
fmt.Println("error querying redis:", err.Error())
}
fmt.Println("count=", count)
con2 := poolB.Get()
defer con2.Close()
count, err = redis.Int(con2.Do("SADD", "any:test", 3246))
if err != nil {
fmt.Println("error querying redis:", err.Error())
}
fmt.Println("count=", count)
con3 := poolC.Get()
defer con3.Close()
count, err = redis.Int(con3.Do("SADD", "any:test", 3246))
if err != nil {
fmt.Println("error querying redis:", err.Error())
}
fmt.Println("count=", count)
}
问题是,所有3个池都连接到最后一个服务器/连接,结果如下所示。 任何的想法?
poolA: localhost:6379
poolB: localhost2:6379
poolC: localhost3:6379
error querying redis: dial tcp: lookup localhost3: no such host
count= 0
error querying redis: dial tcp: lookup localhost3: no such host
count= 0
error querying redis: dial tcp: lookup localhost3: no such host
count= 0
Process finished with exit code 0
答案 0 :(得分:0)
拨号功能使用单变量v
。这些函数在调用时使用分配给v
的最后一个值。
要解决此问题,请在for循环范围内声明一个变量,并在拨号函数中使用该变量:
for k, v := range connections {
v := v // Declare variable scoped inside for loop
redisPool := &redis.Pool{
Dial: func() (redis.Conn, error) {
return redis.Dial("tcp", v) // uses variable scoped inside for loop
},
...
除了这个问题,游泳池设置没有意义。由于池配置为丢弃已空闲10秒的连接,因此借用函数测试永远不会ping服务器。