一.为什么需要Golang连接池

       服务和服务之间的连接是开发过程中很常见的操作,为了服务解耦,减少相互依赖,增强系统稳定性,灵活性,所以会增加许许多多的服务通信链路,随着服务通信链路的增加,网络通信次数就会成倍的增长,那么随之而来的就是网络资源的消耗加剧,例如:带宽,连接数以及cpu,内存等。

  • 每个连接建立时都会申请内存用来做socket buffer
  • 每个连接都要做三次握手四次挥手
  • 每个连接关闭时都要释放内存空间
  • 并发高时,会产生大量的连接,影响系统调度,会占用太多系统资源
二.连接池的实现流程

 2.1 连接池的结构

  • 空闲连接切片:freeConns []*Conn
  • 空闲连接的锁:lastDialErrorMu sync.RWMutex
  • 控制连接池大小的管道:queue chan struct{}

2.2 获取连接

  • 验证连接池是否关闭。
  • 验证是否超过连接池的的最大连接数,没超过计数管道容量减少一个单位;如果超过了1秒后重试,直到重试时间超过最大等待时间则返回失败。
  • 没有超过连接池最大连接数,如果空闲连接切片中有连接,则判断获取到的连接是否超时;如果没有空闲连接则创建一个新连接,创建成功返回,创建失败则将之前技术管道容量减少的一个单位还原。

2.3 释放连接

  • 如果连接失效,则把连接关闭,计数管道容量增加一个单位。
  • 如果连接没有失效,把连接放到空闲连接切片里,计数管道容量增加一个单位。