调用 Go 的 HTTP Client
的 Get\Post
之类的方法时,默认是开启 HTTP keepalive
的,不过直接使用还是会遇到一些情况导致持久连接失效。首先,Client 构造好 HTTP 请求后,利用 Transport 来发送请求并等待结果,默认使用 DefaultTransport
来实现,大多数情况下,自定义 Client 时,配置一下自带的 Transport
即可。
transport
主要围绕着 persistConn
来实现,通过当前请求的 proxy
, scheme
, addr
作为 Key
,对已经建立的连接进行缓存,新的请求来时,先从缓存中取一个连接,如果没有,再新发起一个连接。按照 Go 的基本法,毫无疑问会有两个 goroutine 来分别处理连接上的读和写,然后各种 channel 就开始飞来飞去,于是便让人深思这真的会比基于事件回调的实现简单吗。
可见每次都会有一个请求是新建了个 TCP 连接的,也就是说默认只保持两条持久连接,这是因为这里自定义的的 http.Transport 没有设置 MaxIdleConnsPerHost,于是便采用了默认的 DefaultMaxIdleConnsPerHost,这个值是 2,这是 RFC2616 建议的单个客户端发起的持久连接数,不过在大部分情况下,这个值有点过于保守了。如果把 MaxIdleConnsPerHost 设置为 3,结果便和第一种情况一样。