在Go網(wǎng)絡(luò)請求中配置代理的方法詳解
如何配置代理
不配置代理,本地請求google等會(huì)超時(shí)
package main import ( "fmt" "net/http" "time" ) func main() { // 創(chuàng)建一個(gè)自定義的 Transport 實(shí)例 //transport := &http.Transport{ // Proxy: func(req *http.Request) (*url.URL, error) { // // return url.Parse("http://127.0.0.1:1081") // return url.Parse("socks5://127.0.0.1:1080") // }, //} // 創(chuàng)建一個(gè)自定義的 Client 實(shí)例 client := &http.Client{ //Transport: transport, // 設(shè)置代理 Timeout: time.Second * 3, // 設(shè)置超時(shí) } urlStr := "https://www.google.com/" // 發(fā)送 GET 請求 resp, err := client.Get(urlStr) if err != nil { // 處理錯(cuò)誤 fmt.Println("發(fā)生了錯(cuò)誤:err", err) return } defer resp.Body.Close() // 處理響應(yīng) fmt.Println(resp.StatusCode) }
輸出: 發(fā)生了錯(cuò)誤:err Get "https://www.google.com/": context deadline exceeded (Client.Timeout exceeded while awaiting headers)
取消注釋,則會(huì)輸出 200
go http Client的Transport字段有什么作用
在 Go 的 http 包中,Client 類型代表了 HTTP 客戶端。在 Client 中有一個(gè)名為 Transport 的字段,它是一個(gè) http.RoundTripper 接口類型的值,用于處理 HTTP 請求和響應(yīng)的傳輸細(xì)節(jié)。
通過設(shè)置 Transport 字段,可以對 HTTP 請求進(jìn)行一些自定義設(shè)置,比如設(shè)置代理、設(shè)置超時(shí)、設(shè)置 TLS 客戶端證書等。Transport 字段提供了一些默認(rèn)實(shí)現(xiàn),也可以通過實(shí)現(xiàn) http.RoundTripper 接口來自定義實(shí)現(xiàn)。
例如,可以通過自定義 Transport 來設(shè)置 HTTP 代理:
transport := &http.Transport{ Proxy: func(req *http.Request) (*url.URL, error) { return url.Parse("http://127.0.0.1:8888") }, } client := &http.Client{ Transport: transport, }
在上面的代碼中,通過自定義 Transport 并設(shè)置代理來實(shí)現(xiàn)將所有 HTTP 請求通過本地的代理服務(wù)器進(jìn)行轉(zhuǎn)發(fā)。這樣就可以在代理服務(wù)器上進(jìn)行一些中間人攻擊的操作,如抓包、篡改請求等。
設(shè)置超時(shí)不是這個(gè)字段吧
確實(shí)... 在 Go 的 http.Client 中,超時(shí)是通過 Timeout 字段來設(shè)置的,而 Transport 字段用于控制 HTTP 客戶端的網(wǎng)絡(luò)傳輸設(shè)置,例如代理、TLS 配置、連接池等。超時(shí)時(shí)間是通過 Timeout 字段指定的,而不是 Transport 字段。
我在用go寫一段請求很多個(gè)url然后返回響應(yīng)內(nèi)容的程序,通過設(shè)置http Client的Transport設(shè)置了代理,但發(fā)現(xiàn)大量的EOF,這是什么原因?
在使用 HTTP 客戶端請求多個(gè) URL 時(shí),如果設(shè)置了代理,可能會(huì)導(dǎo)致連接出現(xiàn)大量的 EOF 錯(cuò)誤。這通常是由于代理服務(wù)器在連接到遠(yuǎn)程服務(wù)器時(shí)關(guān)閉了連接,而客戶端仍在嘗試使用已關(guān)閉的連接進(jìn)行通信,從而導(dǎo)致錯(cuò)誤。
一種可能的解決方案是,針對每個(gè)請求創(chuàng)建一個(gè)新的 HTTP 客戶端,并在使用完畢后立即關(guān)閉它。這樣可以確保每個(gè)請求都使用一個(gè)新的連接,避免出現(xiàn)連接復(fù)用的問題。示例代碼如下:
func fetchURL(url string) (string, error) { // 創(chuàng)建一個(gè)自定義的 Transport 實(shí)例 transport := &http.Transport{ Proxy: func(req *http.Request) (*url.URL, error) { return url.Parse("http://127.0.0.1:1080") // 設(shè)置代理 }, } // 創(chuàng)建一個(gè)自定義的 Client 實(shí)例 client := &http.Client{ Transport: transport, // 設(shè)置 Transport Timeout: time.Second * 3, // 設(shè)置超時(shí) } // 發(fā)送 GET 請求 resp, err := client.Get(url) if err != nil { // 處理錯(cuò)誤 return "", err } defer resp.Body.Close() // 讀取響應(yīng)內(nèi)容 body, err := ioutil.ReadAll(resp.Body) if err != nil { // 處理錯(cuò)誤 return "", err } // 返回響應(yīng)內(nèi)容 return string(body), nil } func main() { urls := []string{ "http://example.com", "http://example.org", "http://example.net", } // 遍歷 URL 列表,并發(fā)送請求 for _, url := range urls { resp, err := fetchURL(url) if err != nil { fmt.Printf("fetch %s error: %s\n", url, err) } else { fmt.Printf("fetch %s success: %s\n", url, resp) } } }
此外,還可以嘗試對 Transport 的 MaxIdleConnsPerHost 和 MaxIdleConns 進(jìn)行調(diào)整,以確保連接復(fù)用時(shí)不會(huì)出現(xiàn)連接超時(shí)或連接關(guān)閉的問題。
Transport 的 MaxIdleConnsPerHost 和 MaxIdleConns 是什么意思
Transport的MaxIdleConnsPerHost和MaxIdleConns字段都是用來控制http client連接池的大小和行為的。
- MaxIdleConnsPerHost:指定連接池中每個(gè)主機(jī)允許的最大空閑連接數(shù)。默認(rèn)值是2。
- MaxIdleConns:指定整個(gè)連接池允許的最大空閑連接數(shù)。默認(rèn)值是無限制。
當(dāng)http client創(chuàng)建一個(gè)連接時(shí),它將嘗試重用現(xiàn)有的空閑連接。如果連接池中沒有空閑連接,則http client將創(chuàng)建一個(gè)新的連接。如果連接池中的空閑連接已達(dá)到MaxIdleConns或MaxIdleConnsPerHost,則http client將關(guān)閉連接。
因此,如果將MaxIdleConns和MaxIdleConnsPerHost設(shè)置得太小,那么http client將會(huì)頻繁地關(guān)閉和創(chuàng)建連接,這會(huì)導(dǎo)致一些EOF錯(cuò)誤。可以適當(dāng)?shù)卦黾舆@些字段的值,以減少這些錯(cuò)誤的發(fā)生。
如何設(shè)置?
可以通過在創(chuàng)建 Transport 實(shí)例時(shí)進(jìn)行設(shè)置,例如:
transport := &http.Transport{ MaxIdleConnsPerHost: 10, // 每個(gè)主機(jī)最大空閑連接數(shù) MaxIdleConns: 100, // 最大空閑連接數(shù) }
其中,MaxIdleConnsPerHost 表示每個(gè)主機(jī)最大的空閑連接數(shù),MaxIdleConns 表示所有主機(jī)的最大空閑連接數(shù)。您可以根據(jù)實(shí)際情況進(jìn)行調(diào)整。需要注意的是,如果 MaxIdleConnsPerHost 設(shè)置的太小,可能會(huì)導(dǎo)致無法復(fù)用連接,從而增加了連接的建立和關(guān)閉成本;如果設(shè)置的太大,可能會(huì)占用過多的系統(tǒng)資源。
以上就是在Go網(wǎng)絡(luò)請求中配置代理的方法詳解的詳細(xì)內(nèi)容,更多關(guān)于Go網(wǎng)絡(luò)請求中配置代理的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Go整合captcha實(shí)現(xiàn)驗(yàn)證碼功能
最近在使用Go語言搞一個(gè)用戶登錄&注冊的功能,我們油然會(huì)產(chǎn)生一種增加驗(yàn)證碼的想法。后來在GitHub上找到了這個(gè)名叫captcha的插件,于是就利用文檔進(jìn)行了初步的學(xué)習(xí),并融入到自己的項(xiàng)目中,整個(gè)過程下來感覺這個(gè)插件的設(shè)計(jì)非常巧妙2023-03-03Go 循環(huán)結(jié)構(gòu)for循環(huán)使用教程全面講解
這篇文章主要為大家介紹了Go 循環(huán)結(jié)構(gòu)for循環(huán)使用全面講解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-10-10

使用Go和Tesseract實(shí)現(xiàn)驗(yàn)證碼識(shí)別的流程步驟

go實(shí)現(xiàn)thrift的網(wǎng)絡(luò)傳輸性能及需要注意問題示例解析

Golang 并發(fā)編程入門Goroutine 簡介與基礎(chǔ)用法小結(jié)