标签:def ids 直接 问题 性能 val returns close rpo
// github.com/garyburd/redigo/redis/pool.go 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 // mu protects fields defined below. mu sync.Mutex cond *sync.Cond closed bool active int // 空闲连接队列 idle list.List }
// get prunes stale connections and returns a connection from the idle list or // creates a new connection. func (p *Pool) get() (Conn, error) { p.mu.Lock() //修剪idle列表上那些超时的连接 if timeout := p.IdleTimeout; timeout > 0 { for i, n := 0, p.idle.Len(); i < n; i++ { e := p.idle.Back()//取得idle列表中的最后一个连接(空闲时间最长) if e == nil { break } ic := e.Value.(idleConn) if ic.t.Add(timeout).After(nowFunc()) { //如果空闲时间最长的连接都没有超时,则不再修剪 break } p.idle.Remove(e)//从空闲列表中移除这个连接 p.release()//减少p.active,发消息给阻塞的请求 p.mu.Unlock() ic.c.Close()//关闭连接 p.mu.Lock() } } for { // 从idle列表中获取一个可用的连接 for i, n := 0, p.idle.Len(); i < n; i++ { e := p.idle.Front()//从idle列表前面取连接,是刚刚使用过的连接 if e == nil { break } ic := e.Value.(idleConn) p.idle.Remove(e)//从空闲列表中去除该连接 test := p.TestOnBorrow p.mu.Unlock() if test == nil || test(ic.c, ic.t) == nil {//如果测试函数不为空,则测试这个连接的可用性 return ic.c, nil//可用或者测试方法为空,则返回连接 } ic.c.Close()//不可用,关闭该连接 p.mu.Lock() p.release()//减少p.active,发消息给阻塞的请求 } // 检查pool本身有没有关闭 if p.closed { p.mu.Unlock() return nil, errors.New("redigo: get on closed pool") } // 建立新的连接 if p.MaxActive == 0 || p.active < p.MaxActive {//看看是否没有到最大的active限制 dial := p.Dial p.active += 1 p.mu.Unlock() c, err := dial()//调用dial方法去建立连接 if err != nil { p.mu.Lock() p.release() p.mu.Unlock() c = nil } return c, err } //如果建立连接失败或者建立达到连接池的限制 if !p.Wait {//不阻塞就直接返回错误 p.mu.Unlock() return nil, ErrPoolExhausted } if p.cond == nil { p.cond = sync.NewCond(&p.mu) } p.cond.Wait()//阻塞,等待唤醒 } }
func (p *Pool) put(c Conn, forceClose bool) error { err := c.Err() p.mu.Lock() if !p.closed && err == nil && !forceClose {//p没有关闭,且没有错误,且不是强制关闭连接 p.idle.PushFront(idleConn{t: nowFunc(), c: c})// 把返回的连接放到idle的队首 if p.idle.Len() > p.MaxIdle {// 如果idle列表的长度过长(至多也只能多1) c = p.idle.Remove(p.idle.Back()).(idleConn).c// idle列表的最后一个连接 } else { c = nil } } if c == nil { if p.cond != nil { p.cond.Signal()//成功放回空闲连接通知其他阻塞的进程 } p.mu.Unlock() return nil } p.release()//减少active计数 p.mu.Unlock() return c.Close()//关闭该连接 }
再来看下主要参数
区分两种使用场景:
标签:def ids 直接 问题 性能 val returns close rpo
原文地址:http://www.cnblogs.com/cdyboke/p/7709980.html