Go是如何发送HTTP请求的

2021-07-30  本文已影响0人  迪克dike

一切的一切要从Transport的RoundTrip说起

http.png

重要的角色主要有两个:Transport和PersistConn

Transport中维护了空闲的持久链接
当发起一个http请求,如果没有可重用链接,则会生成可重用链接pConn,生成重用链接会在底层启动两个go协程,一个负责读,一个负责写,roundtrip通过管道与两个协程通信

除了超时退出、出现错误等特殊情况外,重用链接逻辑在readLoop中,通过调用内部函数tryPutIdleConn来放回空闲链接

tryPutIdleConn会在两种情况下调用:

  1. 对于HEAD等这种响应中没有Body的情况,或者检测到Body可写,则认为可以回收。
  2. 其他情况下,需要显示的调用Body.Close()才会重用,因为有个bodyEOFSignal结构,会在调用Body.Close后往waitForBodyRead中发送true,告诉链接可复用。

链接什么时候关闭

  1. 空闲时间太长(90s)
  2. 回收失败。如空闲队列满了等
  3. 其他各种失败的情况

从代码上来看,如果对响应中的Body不做关闭操作的话,会造成go协程的泄露,链接过多没有释放,从而导致内存泄露和fd消耗完毕等情况。

上一篇 下一篇

猜你喜欢

热点阅读