一切的一切要從Transport的RoundTrip說起
重要的角色主要有兩個(gè):Transport和PersistConn
Transport中維護(hù)了空閑的持久鏈接
當(dāng)發(fā)起一個(gè)http請(qǐng)求,如果沒有可重用鏈接,則會(huì)生成可重用鏈接pConn辞州,生成重用鏈接會(huì)在底層啟動(dòng)兩個(gè)go協(xié)程是目,一個(gè)負(fù)責(zé)讀璃诀,一個(gè)負(fù)責(zé)寫跋理,roundtrip通過管道與兩個(gè)協(xié)程通信
除了超時(shí)退出绷跑、出現(xiàn)錯(cuò)誤等特殊情況外椅野,重用鏈接邏輯在readLoop中力奋,通過調(diào)用內(nèi)部函數(shù)tryPutIdleConn來放回空閑鏈接
tryPutIdleConn會(huì)在兩種情況下調(diào)用:
- 對(duì)于HEAD等這種響應(yīng)中沒有Body的情況榜旦,或者檢測到Body可寫,則認(rèn)為可以回收景殷。
- 其他情況下溅呢,需要顯示的調(diào)用Body.Close()才會(huì)重用,因?yàn)橛袀€(gè)bodyEOFSignal結(jié)構(gòu)猿挚,會(huì)在調(diào)用Body.Close后往waitForBodyRead中發(fā)送true咐旧,告訴鏈接可復(fù)用。
鏈接什么時(shí)候關(guān)閉
- 空閑時(shí)間太長(90s)
- 回收失敗绩蜻。如空閑隊(duì)列滿了等
- 其他各種失敗的情況
從代碼上來看铣墨,如果對(duì)響應(yīng)中的Body不做關(guān)閉操作的話,會(huì)造成go協(xié)程的泄露办绝,鏈接過多沒有釋放伊约,從而導(dǎo)致內(nèi)存泄露和fd消耗完畢等情況。