由於Go語言非常易學,且代碼精簡,我們很多同事在研發視頻平台的時候,都喜歡拿Go語言來做編程,我們這個問題就是在使用Go語言做編程的時候出現的,下面就跟大家詳細講一下。
在Go語言編程中,向目標機器發送http請求,獲取內容時,經常會使用以下代碼進行獲取請求后的數據。
body, err := ioutil.ReadAll(resp.Body)
這個代碼對於請求的數據大小不大的情況可以正常使用。但是如果后台數據的大小很大,則會導致內存溢出程序崩潰。
原因分析
Go 語言中 ReadAll() 是一次讀取所有數據,比如一個文件大小為100M,也會將此文件一次性加載到內存中。如果請求過多,很快就會導致內存不夠使用,程序崩潰。
解決辦法
采用 Copy() 或者直接使用 Read() 方法替換掉 ReadAll()。本文中采用 Read() 的方式。
func getTs(req *http.Request) error {
client := http.Client{
Transport: &http.Transport{
ResponseHeaderTimeout: time.Second * 10,
},
//Timeout: time.Second * 10,
}
resp, err := client.Do(req)
// resp, err := http.Get(u)
if err != nil {
return err
}
defer resp.Body.Close()
buffer := make([]byte, 8192)
//result := bytes.NewBuffer(nil)
for {
time.Sleep(200)
_, err := resp.Body.Read(buffer)
if err != nil && err == io.EOF {
break
} else if err != nil {
return err
}
}
return nil
}
如果采用Read()方法,需要注意一下上文中的 err == io.EOF,此段代表文件已經讀取完畢。