更新添加 pthreaded C 客戶端后,問題又出現(xiàn)了,表明連接時(shí)間長是 TCP 協(xié)議的一部分,而不是特定的實(shí)現(xiàn)。改變這些協(xié)議似乎并不容易。初始問題我相信我的問題主要是:Golangnet包在嘗試通過 TCP 連接到服務(wù)器時(shí)做了什么以及:服務(wù)器沒有可用的連接,即使在積壓中也是如此。連接未被拒絕/失敗。5 ms在服務(wù)器響應(yīng)時(shí)間從幾秒增加到幾秒的連接中似乎存在大量開銷。這在生產(chǎn)環(huán)境和下面的最小示例中都可以看到。正確的解決方案是對服務(wù)器使用連接池,這將被實(shí)現(xiàn)。這主要是我的好奇心。重現(xiàn):用 運(yùn)行服務(wù)器backlog = 1,運(yùn)行 client.go。所有 50 個(gè) goroutines 同時(shí)啟動(dòng),總完成時(shí)間將近 2 分鐘。用 運(yùn)行服務(wù)器backlog = 100,運(yùn)行 client.go。所有 50 個(gè) goroutines 同時(shí)觸發(fā),排隊(duì)連接到服務(wù)器,并在~260 ms.使用重試時(shí)間運(yùn)行三個(gè) C 客戶端平均50 us能夠12 ms在平均時(shí)間內(nèi)完成連接,因此沒有看到此問題。示例輸出backlog = 1(第一次是撥號時(shí)間,第二次是完成時(shí)間):但是當(dāng)我使用 goroutines 和 channels 來實(shí)現(xiàn)相同的邏輯時(shí),直接的方法/函數(shù)調(diào)用關(guān)系消失了,因?yàn)?goroutines 使用通道來發(fā)送和接收數(shù)據(jù)。generator := func(integers ...int) <-chan int { intStream := make(chan int) go func() { defer close(intStream) for _, i := range integers { intStream <- i } }() return intStream}multiply := func(intStream <-chan int, multiplier int) <-chan int { multipliedStream := make(chan int) go func() { defer close(multipliedStream) for i := range intStream { multipliedStream <- i*multiplier } }() return multipliedStream}add := func(intStream <-chan int, additive int) <-chan int { addedStream := make(chan int) go func() { defer close(addedStream) for i := range intStream { addedStream <- i+additive } }() return addedStream}intStream := generator(1, 2, 3, 4)pipeline := multiply(add(intStream, 1), 2)for v := range pipeline { fmt.Println(v)}誕生的goroutinegenerator作為生產(chǎn)者發(fā)送整數(shù);add和中誕生的協(xié)程multiply既是生產(chǎn)者又是消費(fèi)者;他們接收整數(shù),處理它們,并將它們放入新的通道中。最后用兩個(gè)channel把這3個(gè)goroutine連接成一個(gè)pipeline,但是我沒有想到要呈現(xiàn)的一目了然。有沒有一種面向goroutines的UML圖?那么,到底是什么原因net.DialTCP(我們也使用了其他風(fēng)格的表盤,沒有明顯區(qū)別)導(dǎo)致表盤時(shí)間變長?嘗試建立連接之間的輪詢時(shí)間?RFC 5681 全局擁塞控制(可能包括互斥鎖?)變量在所有初始連接嘗試失敗時(shí)遞增?還有別的嗎?我傾向于前兩個(gè),因?yàn)檫@些1s, 3s, 5s值似乎是神奇的數(shù)字。它們同時(shí)出現(xiàn)在我的小型本地機(jī)器和大型生產(chǎn)環(huán)境中。
1 回答

動(dòng)漫人物
TA貢獻(xiàn)1815條經(jīng)驗(yàn) 獲得超10個(gè)贊
問題在于 TCP 實(shí)現(xiàn),其中包括重試的指數(shù)退避。Golang 和 C 似乎都沒有一種簡單的方法來改變這種行為。
答案是:如果您的吞吐量很高,請不要打開和關(guān)閉 TCP 連接——使用連接池。
有一些工作著眼于消除指數(shù)退避,鏈接如下,但對于特定情況可能有更好的解決方案。有給我的。
ACM SIGCOMM 計(jì)算機(jī)通信評論,“從 TCP 中移除指數(shù)退避”,第 38 卷,第 5 期,2008 年 10 月。
- 1 回答
- 0 關(guān)注
- 272 瀏覽
添加回答
舉報(bào)
0/150
提交
取消