日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

go tcp连接_TCP漫谈之keepalive和time_wait

發布時間:2024/8/23 编程问答 43 豆豆
生活随笔 收集整理的這篇文章主要介紹了 go tcp连接_TCP漫谈之keepalive和time_wait 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

TCP是一個有狀態通訊協議,所謂的有狀態是指通信過程中通信的雙方各自維護連接的狀態。

一、TCP keepalive

先簡單回顧一下TCP連接建立和斷開的整個過程。(這里主要考慮主流程,關于丟包、擁塞、窗口、失敗重試等情況后面詳細討論。)

首先是客戶端發送syn(Synchronize Sequence Numbers:同步序列編號)包給服務端,告訴服務端我要連接你,syn包里面主要攜帶了客戶端的seq序列號;服務端回發一個syn+ack,其中syn包和客戶端原理類似,只不過攜帶的是服務端的seq序列號,ack包則是確認客戶端允許連接;最后客戶端再次發送一個ack確認接收到服務端的syn包。這樣客戶端和服務端就可以建立連接了。整個流程稱為三次握手。

建立連接后,客戶端或者服務端便可以通過已建立的socket連接發送數據,對端接收數據后,便可以通過ack確認已經收到數據。

數據交換完畢后,通常是客戶端便可以發送FIN包,告訴另一端我要斷開了;另一端先通過ack確認收到FIN包,然后發送FIN包告訴客戶端我也關閉了;最后客戶端回應ack確認連接終止。整個流程成為四次揮手。

TCP的性能經常為大家所詬病,除了TCP+IP額外的header以外,它建立連接需要三次握手,關閉連接需要四次揮手。如果只是發送很少的數據,那么傳輸的有效數據是非常少的。

是不是建立一次連接后續可以繼續復用呢?的確可以這樣做,但這又帶來另一個問題,如果連接一直不釋放,端口被占滿了咋辦。為此引入了今天討論的第一個話題TCP keepalive。所謂的TCP keepalive是指TCP連接建立后會通過keepalive的方式一直保持,不會在數據傳輸完成后立刻中斷,而是通過keepalive機制檢測連接狀態。

Linux控制keepalive有三個參數:保活時間net.ipv4.tcp_keepalive_time、保活時間間隔net.ipv4.tcp_keepalive_intvl、保活探測次數net.ipv4.tcp_keepalive_probes,默認值分別是 7200 秒(2 小時)、75 秒和 9 次探測。如果使用 TCP 自身的 keep-Alive 機制,在 Linux 系統中,最少需要經過 2 小時 + 9*75 秒后斷開。譬如我們SSH登錄一臺服務器后可以看到這個TCP的keepalive時間是2個小時,并且會在2個小時后發送探測包,確認對端是否處于連接狀態。

之所以會討論TCP的keepalive,是因為發現服器上有泄露的TCP連接:

# ll /proc/11516/fd/10lrwx------ 1 root root 64 Jan 3 19:04 /proc/11516/fd/10 -> socket:[1241854730]# dateSun Jan 5 17:39:51 CST 2020

已經建立連接兩天,但是對方已經斷開了(非正常斷開)。由于使用了比較老的go(1.9之前版本有問題)導致連接沒有釋放。

解決這類問題,可以借助TCP的keepalive機制。新版go語言支持在建立連接的時候設置keepalive時間。首先查看網絡包中建立TCP連接的DialContext方法中

if tc, ok := c.(*TCPConn); ok && d.KeepAlive >= 0 {setKeepAlive(tc.fd, true)ka := d.KeepAliveif d.KeepAlive == 0 {ka = defaultTCPKeepAlive}setKeepAlivePeriod(tc.fd, ka)testHookSetKeepAlive(ka)}

其中defaultTCPKeepAlive是15s。如果是HTTP連接,使用默認client,那么它會將keepalive時間設置成30s。

var DefaultTransport RoundTripper = &Transport{Proxy: ProxyFromEnvironment,DialContext: (&net.Dialer{Timeout: 30 * time.Second,KeepAlive: 30 * time.Second,DualStack: true,}).DialContext,ForceAttemptHTTP2: true,MaxIdleConns: 100,IdleConnTimeout: 90 * time.Second,TLSHandshakeTimeout: 10 * time.Second,ExpectContinueTimeout: 1 * time.Second,}

下面通過一個簡單的demo測試一下,代碼如下:

func main() {wg := &sync.WaitGroup{}c := http.DefaultClientfor i := 0; i < 2; i++ {wg.Add(1)go func() {defer wg.Done()for {r, err := c.Get("http://10.143.135.95:8080")if err != nil {fmt.Println(err)return}_, err = ioutil.ReadAll(r.Body)r.Body.Close()if err != nil {fmt.Println(err)return}time.Sleep(30 * time.Millisecond)}}()}wg.Wait()}

執行程序后,可以查看連接。初始設置keepalive為30s。

然后不斷遞減,至0后,又會重新獲取30s。

整個過程可以通過tcpdump抓包獲取。

# tcpdump -i bond0 port 35832 -nvv -A

其實很多應用并非是通過TCP的keepalive機制探活的,因為默認的兩個多小時檢查時間對于很多實時系統是完全沒法滿足的,通常的做法是通過應用層的定時監測,如PING-PONG機制(就像打乒乓球,一來一回),應用層每隔一段時間發送心跳包,如websocket的ping-pong。

二、TCP Time_wait

第二個希望和大家分享的話題是TCP的Time_wait狀態。、

為啥需要time_wait狀態呢?為啥不直接進入closed狀態呢?直接進入closed狀態能更快地釋放資源給新的連接使用了,而不是還需要等待2MSL(Linux默認)時間。

有兩個原因:

一是為了防止“迷路的數據包”,如下圖所示,如果在第一個連接里第三個數據包由于底層網絡故障延遲送達。等待新的連接建立后,這個遲到的數據包才到達,那么將會導致接收數據紊亂。

第二個原因則更加簡單,如果因為最后一個ack丟失,那么對方將一直處于last ack狀態,如果此時重新發起新的連接,對方將返回RST包拒絕請求,將會導致無法建立新連接。

為此設計了time_wait狀態。在高并發情況下,如果能將time_wait的TCP復用,time_wait復用是指可以將處于time_wait狀態的連接重復利用起來。從time_wait轉化為established,繼續復用。Linux內核通過net.ipv4.tcp_tw_reuse參數控制是否開啟time_wait狀態復用。

讀者可能很好奇,之前不是說time_wait設計之初是為了解決上面兩個問題的嗎?如果直接復用不是反而會導致上面兩個問題出現嗎?這里先介紹Linux默認開啟的一個TCP時間戳策略net.ipv4.tcp_timestamps = 1。

時間戳開啟后,針對第一個迷路數據包的問題,由于晚到數據包的時間戳過早會被直接丟棄,不會導致新連接數據包紊亂;針對第二個問題,開啟reuse后,當對方處于last-ack狀態時,發送syn包會返回FIN,ACK包,然后客戶端發送RST讓服務端關閉請求,從而客戶端可以再次發送syn建立新的連接。

最后還需要提醒讀者的是,Linux 4.1內核版本之前除了tcp_tw_reuse以外,還有一個參數tcp_tw_recycle,這個參數就是強制回收time_wait狀態的連接,它會導致NAT環境丟包,所以不建議開啟。

總結

以上是生活随笔為你收集整理的go tcp连接_TCP漫谈之keepalive和time_wait的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 波多野结衣视频在线观看 | 亚洲熟妇av乱码在线观看 | 成人看的毛片 | 亚洲国产精品综合 | 午夜剧场福利社 | 高清国产一区 | 碧蓝之海动漫在线观看免费高清 | 中文字幕日韩欧美 | 国产无遮挡免费观看视频网站 | 欧美日韩中文一区 | 欧美成人一二三 | 爱吃波客今天最新视频 | 精品成人在线观看 | cao久久| 午夜视频精品 | jzjzjz欧美丰满少妇 | 九色视频网站 | 在线色网址 | 免费在线观看黄视频 | 亚洲成av人片在线观看无码 | 伦理av在线| 国产精品自拍亚洲 | 欧美久久久久久久久久久 | 无码人妻av一区二区三区波多野 | 经典三级在线视频 | 久久精品99 | av在线免费观看网站 | 国产成人宗合 | 黄色一级大片在线免费看产 | 亚洲乱熟女一区二区三区小说 | 四虎影视永久免费观看 | 亚洲色图第三页 | 黄床大片 | 七月丁香婷婷 | 国产一区二区在线看 | 欧美性受xxxxxx黑人xyx性爽 | 亚洲91久久| 日本三级欧美三级 | 亚洲美女av在线 | 卡通动漫亚洲综合 | 成人性生交大片免费卡看 | 一级片免费视频 | 亚洲少妇xxx| 香蕉国产 | 日韩黄色三级 | 欧美亚洲另类图片 | 美女伦理水蜜桃4 | 成年人在线免费观看网站 | 97成人资源| 黑丝一区二区三区 | 99成人在线观看 | 成人网站在线进入爽爽爽 | av在线资源站| 日本三级中文字幕在线观看 | 致命魔术电影高清在线观看 | 国产tv在线观看 | 国产精品第13页 | 懂色一区二区二区av免费观看 | 天堂av电影在线观看 | 国产精品av免费观看 | 日韩美女网站 | 欧美三极片| 美女亚洲一区 | 久久人成 | 日韩欧美亚洲一区二区 | 五月在线视频 | 黄色三级带 | 亚欧美精品 | 成人深夜福利在线观看 | 久久国产精品毛片 | 亚洲石原莉奈一区二区在线观看 | 中文字幕第一区综合 | 骚虎av在线| 好吊一区二区三区 | 男女做爰真人视频直播 | av在线免费播放网址 | 午夜性片 | 亚洲呦呦| 欧美一区二区免费 | 高潮毛片又色又爽免费 | 天天5g天天爽免费观看 | 国产日韩欧美久久 | 久久人人爽人人爽人人片亚洲 | 国产cao| 久久中文视频 | 国产视频一区二 | 噜噜在线视频 | 国产一级免费片 | 大黄一级片 | 亚洲av成人无码久久精品 | 日韩av成人在线观看 | 无码一区二区三区在线观看 | 欧美日韩在线视频一区二区 | 日本一级黄色录像 | 丁香六月av | 饥渴的少妇和男按摩师 | 99综合视频 | 色网导航站 | av无码av天天av天天爽 |