使用Go HTTP客戶端打造高性能服務
HTTP(超文本傳輸協(xié)議)是一種用于客戶端和服務器之間傳輸數(shù)據的通信協(xié)議。如果想要訪問服務器資源,HTTP 請求是必不可少的。Go 語言里,net/http 包附帶了默認配置,我們可以適當調整便可以獲得高性能。
大多數(shù)語言都有提供各自的 HTTP 客戶端,文章接下來部分我們將動手實踐如何使用 Go 語言發(fā)起 HTTP 請求,并討論其中有可能遇到的問題。
在做 Go 項目時,我就意識到 HTTP 客戶端如果配置不正確可能會隨時導致服務器崩潰。
在使用 HTTP Client 時,我觀察到一些問題并總結出相應的解決方案,如下所示:
問題一:默認的 HTTP Client
默認情況下,net/http 包自帶的 HTTP 客戶端不帶超時時間。如果你使用的是默認的客戶端 http.DefaultClient(),這個是不帶超時時間的。
假如你請求外部的 API 掛了,發(fā)出的請求沒響應導致連接一直出于打開狀態(tài)。隨著請求數(shù)越來越多,連接數(shù)隨之增加,導致耗盡服務器的資源,最后服務器隨之崩潰。
解決辦法:不要使用默認的 HTTP 客戶端,根據實際情況設置超時時間。
var httpClient = &http.Client{
Timeout: time.Second * 10,
}
對于 API 接口,超時時間建議不需要超過 10s,如果請求在 10s 內沒有返回,則請求會取消并報錯:request canceled (Client.Timeout exceeded …) 。
問題二:默認的 Http Transport
默認情況下,HTTP 客戶端會維護一個連接池。當請求完成之后,連接會保持打開狀態(tài)直到空閑時間超時(默認是 90s)自動斷開。如果有請求過來,會優(yōu)先使用已打開的連接而不是創(chuàng)建新的連接,請求完成之后,連接會返還到連接池中。
使用連接池將使用最少的服務器資源處理更多的 API 請求。
如果沒有自定義 HTTP 客戶端的 transport,將會使用默認配置。
HTTP Transport 的默認配置如下:
var DefaultTransport RoundTripper = &Transport{
...
MaxIdleConns: 100,
IdleConnTimeout: 90 * time.Second,
...
}
const DefaultMaxIdleConnsPerHost = 2
MaxIdleConns 表示連接池大小,是可以打開的最大連接數(shù),默認值是 100。
參數(shù) DefaultMaxIdleConnsPerHost 的默認值是 2,表示每個主機(host)的打開連接數(shù)。這意味著,連接池中 100 個連接只有兩個連接分配給該主機。
隨著請求增多,但是只有兩個請求被處理,其他請求只能被迫等待并進入 TIME_WAIT 狀態(tài)。請求增多,進入 TIME_WAIT 狀態(tài)的連接數(shù)增多,消耗越來越多的服務器資源,當達到服務器瓶頸時,服務器將會崩潰。
解決辦法:提高 MaxIdleConnsPerHost 數(shù)值,不要使用默認的 Transport。
t := http.DefaultTransport.(*http.Transport).Clone()
t.MaxIdleConns = 100
t.MaxConnsPerHost = 100
t.MaxIdleConnsPerHost = 100
httpClient = &http.Client{
Timeout: 10 * time.Second,
Transport: t,
}
通過增加每個主機的連接數(shù)和空閑連接數(shù),就有助于提高性能并以最少的服務器資源處理更多請求。
可以根據服務器資源和實際需求適當增加連接池大小和每個主機的連接數(shù)。
總結
這篇文章中,我們圍繞 net/http 包討論了默認配置的一些問題。通過更改 HTTP 客戶端的一些默認設置,在生產環(huán)境中也可以獲得高性能的 HTTP 客戶端。
到此這篇關于使用Go HTTP客戶端打造高性能服務的文章就介紹到這了,更多相關Go HTTP客戶端高性能內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Go語言使用Timeout Context取消任務的實現(xiàn)
本文主要介紹了Go語言使用Timeout Context取消任務的實現(xiàn),包括基本的任務取消和控制HTTP客戶端請求的超時,具有一定的參考價值,感興趣的可以了解一下2024-01-01
本地使用Docker搭建go開發(fā)環(huán)境的全過程
最近想學習一下golang,自己之前一直把環(huán)境全部安裝在docker上,所以這次也想把golang的環(huán)境安裝在docker上,下面這篇文章主要給大家介紹了關于本地使用Docker搭建go開發(fā)環(huán)境的相關資料,需要的朋友可以參考下2022-07-07

