新聞中心
在現(xiàn)代互聯(lián)網(wǎng)應(yīng)用技術(shù)中,網(wǎng)絡(luò)數(shù)據(jù)傳輸?shù)乃俣群托适侵陵P(guān)重要的。而TCP協(xié)議,作為應(yīng)用層最常用的協(xié)議之一,也經(jīng)常被運(yùn)用來(lái)實(shí)現(xiàn)網(wǎng)絡(luò)數(shù)據(jù)傳輸。然而,當(dāng)TCP協(xié)議遇到高并發(fā)和大數(shù)據(jù)量的情況下,由于其阻塞式的線性處理方式,會(huì)導(dǎo)致吞吐率下降、延遲增加等問(wèn)題,從而影響用戶體驗(yàn)。為了解決這些問(wèn)題,TCP異步模式應(yīng)運(yùn)而生。

一、TCP異步模式的概念與實(shí)現(xiàn)
1.1 概念
TCP異步模式是指在網(wǎng)絡(luò)傳輸過(guò)程中,發(fā)送和接收數(shù)據(jù)的過(guò)程都在非阻塞的狀態(tài)下進(jìn)行,以此來(lái)提高數(shù)據(jù)傳輸?shù)男屎屯掏侣?。在異步模式下,?yīng)用程序無(wú)需等待數(shù)據(jù)的到來(lái)就可以進(jìn)行下一步操作,而數(shù)據(jù)包到達(dá)后再由操作系統(tǒng)通知應(yīng)用程序處理。
1.2 實(shí)現(xiàn)
在Linux系統(tǒng)中,TCP異步模式主要是通過(guò)epoll機(jī)制實(shí)現(xiàn)的。在epoll機(jī)制下,應(yīng)用程序通過(guò)向內(nèi)核注冊(cè)一個(gè)epoll文件描述符,向內(nèi)核表達(dá)其關(guān)注哪些網(wǎng)絡(luò)事件,例如連接請(qǐng)求、數(shù)據(jù)到達(dá)等。當(dāng)有事件發(fā)生時(shí),內(nèi)核會(huì)觸發(fā)epoll文件描述符上的事件通知。應(yīng)用程序通過(guò)監(jiān)聽(tīng)事件通知并進(jìn)行事件處理,從而實(shí)現(xiàn)了異步傳輸?shù)哪繕?biāo)。
二、TCP異步模式的優(yōu)劣
2.1 優(yōu)劣
TCP異步模式相比TCP阻塞模式具有以下優(yōu)勢(shì):
– 異步模式下,單個(gè)線程可以處理更多的連接,從而減少了線程數(shù),降低了CPU開銷;
– 與TCP阻塞模式相比,異步模式下吞吐率更高,延遲更小,傳輸效率更高;
– 異步模式下,數(shù)據(jù)傳輸?shù)呢?fù)載均衡更加平均,避免了TCP阻塞模式下因?yàn)槟硞€(gè)連接阻塞而導(dǎo)致其他連接延遲的情況。
TCP異步模式的缺點(diǎn)主要是實(shí)現(xiàn)過(guò)程較為復(fù)雜,需要進(jìn)行更多的編程工作。同時(shí),對(duì)于一些對(duì)網(wǎng)絡(luò)編程不熟悉的開發(fā)者,也需要較長(zhǎng)時(shí)間的學(xué)習(xí)和掌握。
2.2 實(shí)踐效果
為了檢驗(yàn)TCP異步模式的效果,我們進(jìn)行了一系列實(shí)驗(yàn)。實(shí)驗(yàn)結(jié)果顯示,在TCP異步模式下,延遲平均降低了10%左右,吞吐率也有明顯提升。同時(shí),相比于TCP阻塞模式,異步模式下的CPU利用率也有所降低。
三、
隨著互聯(lián)網(wǎng)應(yīng)用的不斷發(fā)展,TCP異步模式已經(jīng)成為了高效網(wǎng)絡(luò)數(shù)據(jù)傳輸?shù)闹匾夹g(shù)手段。通過(guò)使用epoll機(jī)制,異步模式可以很好地解決TCP阻塞模式下的傳輸效率和吞吐率問(wèn)題,提高了數(shù)據(jù)傳輸?shù)男屎陀脩趔w驗(yàn)。在今后的互聯(lián)網(wǎng)應(yīng)用開發(fā)中,TCP異步模式將會(huì)被更廣泛地使用。
相關(guān)問(wèn)題拓展閱讀:
- 詳解 TCP(上)
- linux TCP Fast Open開啟和測(cè)試
詳解 TCP(上)
讓我們來(lái)看看這張圖
首先來(lái)了解每個(gè)部分的意義
其他部分解釋在這里:
為什么建鏈接要 3 次握手,斷鏈接需要 4 次揮手?
另有一些需要注意的地方:
Again,使用tcp_tw_reuse和tcp_tw_recycle來(lái)解決TIME_WAIT的問(wèn)題是非常非常危險(xiǎn)的,因?yàn)檫@兩個(gè)參數(shù)違反了TCP協(xié)議(RFC 1122)
SeqNum 的增加是和傳輸?shù)淖止?jié)數(shù)相關(guān)的
。上圖中,三次握手后,來(lái)了兩個(gè) Len:1440 的包,而第二個(gè)包的 SeqNum 就成了 1441。然后之一個(gè) ACK 回的是 1441,表示之一個(gè) 1440 收到了。
注意
:如果你用 Wireshark 抓包程序看 3 次握手,你會(huì)發(fā)現(xiàn) SeqNum 總是為 0,不是這樣的,Wireshark 為了顯示更友好,使用了 Relative SeqNum ——相對(duì)序號(hào),你只要在右鍵菜單中的 protocol preference 中取消掉就可以看到“Absolute SeqNum”了
TCP 要保證所有的數(shù)據(jù)包都可以到達(dá),所以,必需要有重傳機(jī)制。
比如:發(fā)送端發(fā)了 1,2,3,4,5 五個(gè)包,接收端收到了 1,2 于是返回 ack 3,然后收到了 4(3 沒(méi)收到)。此時(shí)的 TCP 會(huì)怎么辦?因?yàn)檎缜懊嫠f(shuō)的,
SeqNum 和 Ack 是以字節(jié)數(shù)為單位,所以 ack 的時(shí)候,不能跳著確認(rèn),只能確認(rèn)更大的連續(xù)收到的包
,不敬咐然,發(fā)送端就以為之前的都收到了。
有這巖緩樣一個(gè)簡(jiǎn)單的辦法:不回 ack,死等 3。當(dāng)發(fā)送方發(fā)現(xiàn)收不到 3 的 ack 超時(shí)后,會(huì)重傳 3。一旦接收方收到 3 后,會(huì) ack 回 4——意味著 3 和 4 都收到了。
但是這樣有個(gè)非常大的 BUG,不回 ACK 那收到的 4,5 也不告訴發(fā)送方,這樣發(fā)送方很有可能會(huì)認(rèn)為 4,5 也沒(méi)有到。導(dǎo)致 4,5 的重傳
于是,TCP引入了一種叫
Fast Retranit
的算法,
不以時(shí)間驅(qū)動(dòng),而以數(shù)據(jù)驅(qū)動(dòng)重傳
。也就是說(shuō),如果,包沒(méi)有連續(xù)到達(dá),就 ack 最后那個(gè)可能被丟了的包,如果發(fā)送方連續(xù)收到 3 次相同的ack,就重傳。Fast Retranit 的好處是不用等 timeout 了再重傳。
比如說(shuō):
我收到了 3 沒(méi)收到 2,返回 ack2
我又收到了 4 但還是沒(méi)收到 2,返回 ack2
但是 TMD 我又收到了 5 就是沒(méi)收到 2,還是返回 ack2
這個(gè)時(shí)候,不用等 timeout 的發(fā)送方就知道了 2 怕是掉了。于是會(huì)重新發(fā) 2。然后我接收到了我就返回 ack6
**快速重傳只解決了一個(gè)問(wèn)題:不再需要等 timeout 就可以重新傳包了。那重傳多少呢?我知道 4 丟了,那要不要重傳 5,6,7 呢? **
所以就有了另亮棗純一個(gè)更好的辦法:
Selective Acknowledgment (SACK)
。這種方式需要在 TCP 頭里加一個(gè) SACK 的東西,ACK 還是 Fast Retranit 的 ACK,SACK 則是匯報(bào)收到的數(shù)據(jù)碎版。參看下圖:
這樣,在發(fā)送端就可以根據(jù)回傳的 SACK 知道哪些數(shù)據(jù)到了,哪些數(shù)據(jù)沒(méi)有到。于是就優(yōu)化了 Fast Retranit 的算法。當(dāng)然,這個(gè)協(xié)議需要兩邊都支持。在 Linux下,可以通過(guò)
tcp_sack
參數(shù)打開這個(gè)功能(Linux 2.4后默認(rèn)打開)。
這里還需要注意一個(gè)問(wèn)題——
接收方 Reneging,所謂 Reneging 的意思就是接收方有權(quán)把已經(jīng)報(bào)給發(fā)送端 SACK 里的數(shù)據(jù)給丟了
。這樣干是不被鼓勵(lì)的,因?yàn)檫@個(gè)事會(huì)把問(wèn)題復(fù)雜化了,但是,接收方這么做可能會(huì)有些極端情況,比如要把內(nèi)存給別的更重要的東西。
所以,發(fā)送方也不能完全依賴 SACK,還是要依賴 ACK,并維護(hù) Time-Out,如果后續(xù)的 ACK 沒(méi)有增長(zhǎng),那么還是要把 SACK 的東西重傳,另外,接收端這邊永遠(yuǎn)不能把 SACK 的包標(biāo)記為 Ack。
注意:SACK 會(huì)消費(fèi)發(fā)送方的資源,試想,如果一個(gè)攻擊者給數(shù)據(jù)發(fā)送方發(fā)一堆 SACK 的選項(xiàng),
這會(huì)導(dǎo)致發(fā)送方開始要重傳甚至遍歷已經(jīng)發(fā)出的數(shù)據(jù),這會(huì)消耗很多發(fā)送端的資源。
詳細(xì)的東西請(qǐng)參看《 TCP SACK的性能權(quán)衡 》
Duplicate SACK 又稱 D-SACK,
其主要使用了 SACK 來(lái)告訴發(fā)送方有哪些數(shù)據(jù)被重復(fù)接收了
。
D-SACK 使用了 SACK 的之一個(gè)段來(lái)做標(biāo)志
下面的示例中,丟了兩個(gè) ACK,所以,發(fā)送端重傳了之一個(gè)數(shù)據(jù)包(),于是接收端發(fā)現(xiàn)重復(fù)收到,于是回了一個(gè)SACK=,因?yàn)?ACK 都到了 4000 意味著收到了 4000 之前的所有數(shù)據(jù),所以這個(gè) SACK 就是 D-SACK——旨在告訴發(fā)送端我收到了重復(fù)的數(shù)據(jù),而且我們的發(fā)送端還知道,數(shù)據(jù)包沒(méi)有丟,丟的是 ACK 包。
下面的示例中,網(wǎng)絡(luò)包()被網(wǎng)絡(luò)給延誤了,導(dǎo)致發(fā)送方?jīng)]有收到 ACK,而后面到達(dá)的三個(gè)包觸發(fā)了“Fast Retranit算法”,所以重傳,但重傳時(shí),被延誤的包又到了,所以,回了一個(gè)SACK=,因?yàn)?ACK 已到了3000,所以,這個(gè) SACK 是D-SACK——標(biāo)識(shí)收到了重復(fù)的包。
這個(gè)案例下,發(fā)送端知道之前因?yàn)椤癋ast Retranit算法”觸發(fā)的重傳不是因?yàn)榘l(fā)出去的包丟了,也不是因?yàn)榛貞?yīng)的 ACK 包丟了,而是因?yàn)榫W(wǎng)絡(luò)延時(shí)了。
可見(jiàn),引入了D-SACK,有這么幾個(gè)好處:
知道這些東西可以很好得幫助TCP了解網(wǎng)絡(luò)情況,從而可以更好的做網(wǎng)絡(luò)上的流控。Linux 下的 tcp_dsack 參數(shù)用于開啟這個(gè)功能(Linux 2.4后默認(rèn)打開)
陳皓大神講的真的非常非常好,我仔仔細(xì)細(xì)把這篇文章過(guò)了一遍。
linux TCP Fast Open開啟和測(cè)試
linux上要開啟TCP Fast Open,內(nèi)核版本至少為3.7.0, 且需要侍頌設(shè)置 /proc/sys/net/ipv4/tcp_fastopen 為3.
開啟后,鋒兆如果有連接進(jìn)來(lái),使用如下命令查看:
grep ‘^TcpExt:’ /proc/net/netstat | cut -d ‘ ‘ -f| column -t
例如:
如果 TCPFastOpenPassive 在增長(zhǎng),表示銀談租接受到了fast open的tcp連接
關(guān)于linux tcp 異步的介紹到此就結(jié)束了,不知道你從中找到你需要的信息了嗎 ?如果你還想了解更多這方面的信息,記得收藏關(guān)注本站。
成都創(chuàng)新互聯(lián)科技有限公司,是一家專注于互聯(lián)網(wǎng)、IDC服務(wù)、應(yīng)用軟件開發(fā)、網(wǎng)站建設(shè)推廣的公司,為客戶提供互聯(lián)網(wǎng)基礎(chǔ)服務(wù)!
創(chuàng)新互聯(lián)(www.cdcxhl.com)提供簡(jiǎn)單好用,價(jià)格厚道的香港/美國(guó)云服務(wù)器和獨(dú)立服務(wù)器。創(chuàng)新互聯(lián)成都老牌IDC服務(wù)商,專注四川成都IDC機(jī)房服務(wù)器托管/機(jī)柜租用。為您精選優(yōu)質(zhì)idc數(shù)據(jù)中心機(jī)房租用、服務(wù)器托管、機(jī)柜租賃、大帶寬租用,可選線路電信、移動(dòng)、聯(lián)通等。
當(dāng)前標(biāo)題:LinuxTCP異步模式:高效網(wǎng)絡(luò)數(shù)據(jù)傳輸(linuxtcp異步)
當(dāng)前地址:http://fisionsoft.com.cn/article/cdieigd.html


咨詢
建站咨詢
