寫 go 時 要記得做資源釋放
最近在寫 go 時,碰到一個地雷,花了一整天,最終發現是很基本的問題,看來自己功力還是太淺,在這方面還需要多加強,在這裡紀錄一下歷程
首先我最近因為 Demo 需要,做了一個 guser proxy (gusher介紹),降低其他 application 存取複雜度。
func main() {
u:="http://xxx.com/api"
client := &http.Client{}
i:=0
for i<100 {
v := url.Values{}
v.Add("content", "test")
req, err := http.NewRequest("POST", u, bytes.NewBufferString(v.Encode()))
_,err:=client.Do(req)
i++
}
}
這是一個簡單的 simple code,基本上就是重複的對一個 url 發出 request,我踩到的地雷就是因為個人偷懶,把 client 回傳的 response,直接忽略掉,導致資源一直咬著,最後會觸發 Socket:too many open files
。
後來利用 lsof
指令去觀看開啟資源,才發現這個疏忽,解法如下
func main() {
u:="http://xxx.com/api"
client := &http.Client{}
i:=0
for i<100 {
v := url.Values{}
v.Add("content", "test")
req, err := http.NewRequest("POST", u, bytes.NewBufferString(v.Encode()))
resp,err:=client.Do(req)
resp.Body.Close()
i++
}
}
經過這次教訓,其實又認識了很多 linux 底層的東西,跟一些指令除錯,之前從同事那邊學到一句蠻受用的名言
每個 error 都乖乖處理,不要忽略,就不會發生不預期的錯誤
這次我給自己的一句話就是
每個 return 都要乖乖處理,不要偷懶,才不會忘記要做資源釋放