亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

多個 http.Requests 給出“無法分配請求的地址”,除非加速

多個 http.Requests 給出“無法分配請求的地址”,除非加速

Go
30秒到達戰場 2021-10-25 20:15:18
使用下面的客戶端代碼(以及此框上端口 8088 上的偵聽 Web 服務器),在從以下位置彈出此錯誤之前,我很少能夠獲得超過 23000 次點擊client.Get():panic: Get http://localhost:8088/: dial tcp 127.0.0.1:8088: can't assign requested address奇怪的是,如果我增加計時器延遲(即從一毫秒到一微秒),需要更多的點擊才能獲得錯誤,170,000 甚至更多。查看網絡流量,每個客戶端連接在斷開連接之前只使用了幾次(即客戶端發送一個 FIN)。很明顯,它正在建立許多 TCP 連接并溢出套接字表。鑒于 Golang HTTP 文檔說默認情況下啟用了 keepalive,我不希望出現這種情況。內核跟蹤顯示在關閉之前底層套接字沒有發出任何錯誤(EAGAIN 除外,這是預期的并且并不總是在套接字關閉之前)。這是 OSX (14.4.0) 上的 Go 1.4.2。為什么客戶端連接沒有一直被重用?package mainimport (    "io/ioutil"    "net/http"    "runtime"    "sync"    "time")var reqnum = 0func hit(client *http.Client) {    resp, err := client.Get("http://localhost:8088/")    if err != nil {        println(reqnum)        panic(err)    }    defer resp.Body.Close()    _, err = ioutil.ReadAll(resp.Body)    if err != nil {        panic(err)    }    reqnum++ // not thread safe, but shouldn't cause errors.}func main() {    var wg sync.WaitGroup    runtime.GOMAXPROCS(runtime.NumCPU())    client := &http.Client{}    for i := 0; i < 10; i++ {        wg.Add(1)        go func() {            defer wg.Done()            ticker := time.NewTicker(time.Microsecond * 1000)            for j := 0; j < 120000; j++ {                <-ticker.C                hit(client)            }            ticker.Stop()        }()    }    wg.Wait()}
查看完整描述

1 回答

?
阿波羅的戰車

TA貢獻1862條經驗 獲得超6個贊

can't assign requested address撥號期間的錯誤是由于用于客戶端連接的本地臨時端口用完了。端口用完的原因僅僅是因為您建立的連接太多,速度太快。當您加快連接速率時會發生什么,您開始捕捉空閑連接在它們關閉之前返回到池中。有一個代碼路徑可以在撥號期間捕獲這些新的空閑連接以更快地返回連接,但是沒有辦法每次都確定性地捕獲這些連接。

由于您僅連接到一臺主機(如評論中所述),因此您需要做的是將其設置得Transport.MaxIdleConnsPerHost更高。您需要查看它在太多開放連接之間以及何時開始過快回收它們之間的平衡。

在客戶端上使用信號量甚至可能是有利的,以防止過多的同時連接,這將開始導致連接再次過快回收。


查看完整回答
反對 回復 2021-10-25
  • 1 回答
  • 0 關注
  • 272 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號