redigo提示connection pool exhausted
版权声明 本站原创文章 由 萌叔 发表 转载请注明 萌叔 | http://vearne.cc 1. 引言 线上的某个服务(Golang开发)使用Redis作为消息队列,使用的redis库是garyburd/redigo, 这两天出现如下错误 connection pool exhausted 2. 产生原因 阅读源码pool.go 阅读get()即可 type Pool struct { // Dial()方法返回一个连接,从在需要创建连接到的时候调用 Dial func() (Conn, error) // TestOnBorrow()方法是一个可选项,该方法用来诊断一个连接的健康状态 TestOnBorrow func(c Conn, t time.Time) error // 最大空闲连接数 MaxIdle int // 一个pool所能分配的最大的连接数目 // 当设置成0的时候,该pool连接数没有限制 MaxActive int // 空闲连接超时时间,超过超时时间的空闲连接会被关闭。 // 如果设置成0,空闲连接将不会被关闭 // 应该设置一个比redis服务端超时时间更短的时间 IdleTimeout time.Duration // 如果Wait被设置成true,则Get()方法将会阻塞 Wait bool ... ... } 以上异常的原因是这样的,在garyburd/redigo中,得到连接的步骤如下 尝试从空闲列表中,获得一个可用连接;如果成功直接返回,失败则尝试步骤2 如果当前的Active 连接数 < MaxActive,则尝试创建一个新连接;如果成功直接返回,失败则尝试步骤3 判断Wait为true则等待,否则报出异常 // ErrPoolExhausted is returned from a pool connection method (Do, Send, // Receive, Flush, Err) when the maximum number of database connections in the // pool has been reached. var ErrPoolExhausted = errors.New("redigo: connection pool exhausted") 3. 解决方法 设置MaxActive,设MaxActive=0(表示无限大)或者足够大。 设置Wait=true,当程序执行get(),无法获得可用连接时,将会暂时阻塞。 4. 完整的初始化连接池的代码 func NewRedisPool(redisConf context.RedisConf) *redis.Pool { address := fmt.Sprintf("%v:%v", redisConf.Host, redisConf.Port) dbOption := redis.DialDatabase(redisConf.Db) pwOption := redis.DialPassword(redisConf.Password) // **重要** 设置读写超时 readTimeout := redis.DialReadTimeout(time.Second * time.Duration(redisConf.ConTimeout)) writeTimeout := redis.DialWriteTimeout(time.Second * time.Duration(redisConf.ConTimeout)) conTimeout := redis.DialConnectTimeout(time.Second * time.Duration(redisConf.ConTimeout)) redisPool := &redis.Pool{ // 从配置文件获取maxidle以及maxactive,取不到则用后面的默认值 MaxIdle: redisConf.MaxIdleConn, MaxActive: redisConf.MaxActiveConn, // **重要** 如果空闲列表中没有可用的连接 // 且当前Active连接数 < MaxActive // 则等待 Wait: true, IdleTimeout: time.Duration(redisConf.IdleTimeout) * time.Second, Dial: func() (redis.Conn, error) { c, err := redis.Dial("tcp", address, dbOption, pwOption, readTimeout, writeTimeout, conTimeout) if err != nil { return nil, err } return c, nil }, } return redisPool }