Go语言 连接池相关总结:HTTP、RPC、Redis 和数据库等( 三 )


除此之外,h2 的 connpool 和 h1 的没什么区别 。
从 idleConn 数组中获取 idle 连接时:
func (t *Transport) queueForIdleConn(w *wantConn) (delivered bool) {   if delivered {    if pconn.alt != nil {     // HTTP/2: multiple clients can share pconn.     // Leave it in the list.    } else {     // HTTP/1: only one client can use pconn.     // Remove it from the list.     t.idleLRU.remove(pconn)     list = list[:len(list)-1]    }   }把使用完的连接放回连接池时:
 // HTTP/2 (pconn.alt != nil) connections do not come out of the idle list, // because multiple goroutines can use them simultaneously. // If this is an HTTP/2 connection being “returned,” we're done. if pconn.alt != nil && t.idleLRU.m[pconn] != nil {  return nil } if pconn.alt == nil {   // HTTP/1.   // Loop over the waiting list until we find a w that isn't done already, and hand it pconn.   for q.len() > 0 {    w := q.popFront()    if w.tryDeliver(pconn, nil) {     done = true     break    }   }  } else {   // HTTP/2.   // Can hand the same pconn to everyone in the waiting list,   // and we still won't be done: we want to put it in the idle   // list unconditionally, for any future clients too.   for q.len() > 0 {    w := q.popFront()    w.tryDeliver(pconn, nil)   }  }

  • 如果 LRU 列表非空,说明当前没有等待的 goroutine,而在获取 http2 连接时,并没有把连接从连接池中真地拿走,所以直接返回就行了 。
  • 如果 LRU 列表为空,这条可能是新建的连接,需要把 waitqueue 弹到空,并把当前这条连接放进连接池 。
fasthttp服务端请求处理 5
fasthttp 的 server 端使用 worker pool 来进行 goroutine 复用,不会频繁创建新的 g 。
workerPool.workerFunc 就是每个 worker 的主循环:
func (wp *workerPool) workerFunc(ch *workerChan) { var c net.Conn for c = range ch.ch {  if c == nil {   break  }  wp.WorkerFunc(c) } wp.lock.Lock() wp.workersCount-- wp.lock.Unlock()}每次 serve 新的 conn 时:
  1. 从 workerpool 中获取一个 worker,没有就新建,启动 workerFunc 主循环,监听 worker channel 。
  2. 把当前 serve 的新连接发送到 worker channel
  3. workerFunc 获取到新 conn,即开始请求处理流程 。执行 fasthttp.Server.serveConn
客户端连接池type HostClient struct { // Maximum number of connections which may be established to all hosts // listed in Addr. // // You can change this value while the HostClient is being used // using HostClient.SetMaxConns(value) // // DefaultMaxConnsPerHost is used if not set. MaxConns int // Keep-alive connections are closed after this duration. // // By default connection duration is unlimited. MaxConnDuration time.Duration // Idle keep-alive connections are closed after this duration. // // By default idle connections are closed // after DefaultMaxIdleConnDuration. MaxIdleConnDuration time.Duration // Maximum number of attempts for idempotent calls // // DefaultMaxIdemponentCallAttempts is used if not set. MaxIdemponentCallAttempts int        // Maximum duration for waiting for a free connection. // // By default will not waiting, return ErrNoFreeConns immediately MaxConnWaitTimeout time.Duration clientName  atomic.Value lastUseTime uint32 connsLock  sync.Mutex connsCount int conns      []*clientConn connsWait  *wantConnQueue}


推荐阅读