自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

為什么你必須得學(xué)些 TCP 的知識?

網(wǎng)絡(luò) 網(wǎng)絡(luò)管理
當(dāng)我還在 Recurse Center 的時候,我用 Python 寫過 TCP 協(xié)議棧(還寫過一篇文章:如果你用 Python 寫 TCP 協(xié)議棧會遇到什么?)。這是一次有趣的學(xué)習(xí)經(jīng)歷,但是也僅此而已。

這不是指要明白 TCP 的所有東西,也不是說要通讀 《TCP/IP 詳解》。不過懂一點 TCP 知識是很有必要的。理由如下:

當(dāng)我還在 Recurse Center 的時候,我用 Python 寫過 TCP 協(xié)議棧(還寫過一篇文章:如果你用 Python 寫 TCP 協(xié)議棧會遇到什么?)。這是一次有趣的學(xué)習(xí)經(jīng)歷,但是也僅此而已。

一年以后,工作中有人在 Slack 上提到:“嘿,我在向 NSQ 發(fā)布消息時,每次要耗費 40 毫秒”。我已經(jīng)斷斷續(xù)續(xù)思考了一個星期,但是沒有任何結(jié)果。

一點背景知識:NSQ 是一個消息隊列,你通過本地的一個 HTTP 請求向其發(fā)布消息。發(fā)送本地的一個 HTTP 請求確實不應(yīng)該花費 40 毫秒,有時候會更差。NSQ 守護(hù)進(jìn)程的負(fù)載不高,也沒有使用過多的內(nèi)存,也看不到 GC 停頓。這究竟是為什么呢?神吶,救救我吧!

 [[161136]]

突然我記起我一周以前看過的一篇叫做“性能研究(In search of performance)”的文章——我們?nèi)绾螢槊總€ POST 請求節(jié)省 200ms。在這篇文章中,他們說到為什么每個 POST 請求會花費額外的 200 毫秒。就是這個原因。這是該文章中的關(guān)鍵段落:

延遲確認(rèn)(ACK) 與 TCP_NODELAY

Ruby 的 Net::HTTP 會將 POST 請求切分為兩個 TCP 包,一個消息頭,一個消息體。相反,curl 會將這兩者合并為一個包。更糟糕的是,Net::HTTP 在打開 TCP 套接字時不會設(shè)置 TCP_NODELAY,這將導(dǎo)致第二個包需要等到第一個包的接收確認(rèn)通知之后才能發(fā)送。這是 Nagle 算法導(dǎo)致的。

轉(zhuǎn)換到連接的另一端,HAProxy 需要決定如何確認(rèn)這兩個包。在 1.4.18 版本中(我們正在用的版本),它是通過 TCP 延遲確認(rèn)通知來實現(xiàn)的。延遲確認(rèn)對 Nagle 算法有非常糟糕的影響,會導(dǎo)致請求暫停直到服務(wù)器延遲確認(rèn)超時。

現(xiàn)在我們解釋這個段落說的內(nèi)容。

TCP 是一個通過數(shù)據(jù)包傳輸數(shù)據(jù)的算法

他們的 HTTP 庫將 POST 請求分割成兩個小的數(shù)據(jù)包發(fā)送

接下來,TCP 采用類似如下的步驟進(jìn)行交互:

application:Hi!這里有一個數(shù)據(jù)包。

HAProxy:(沉默),等待第二個包發(fā)送

HAProxy:對了,我需要返回一個確認(rèn),不過沒關(guān)系,等會吧

application: (沉默)

application:好吧,我正在等待確認(rèn),可能現(xiàn)在網(wǎng)絡(luò)延遲比較大

HAProxy:好吧,太煩人了,這是一個確認(rèn)。

application:好極了,這是第二個數(shù)據(jù)包!!!

HAProxy:親,我們已經(jīng)搞定了。

這個過程是不是應(yīng)用程序和 HAProxy 都在消極等待另一方發(fā)送信息?這就是那額外的 200ms。應(yīng)用程序這么做的是因為 Nagle 算法,而 HAProxy 消息等待的原因是延遲確認(rèn)。

據(jù)我所知,延遲確認(rèn)是所有 Linux 系統(tǒng)的默認(rèn)行為。所以這不是一個偶然或者異常情況,如果發(fā)送 TCP 數(shù)據(jù)包多一個 1 個,你就會遇到這種情況。

現(xiàn)在,我們成為專家了

讀過這篇文章之后我很快就忘了。不過當(dāng)我被額外的 40 毫秒難住的時候,我又記起來了。

所以我認(rèn)為——這不可能是我的問題,可能嗎?可能嗎??然后我發(fā)了一封郵件給我團(tuán)隊說:“我想我快要瘋了,但是這可能是 TCP 的問題”。

所以我提交了一次修訂,將我的應(yīng)該調(diào)整為 TCP_NODELAY,然后問題就“嘣”的一聲解決了。

40 毫秒的延遲立馬就消失了。所有的事情都解決了,我就是個天才。

我們是否應(yīng)該完全停止使用延遲確認(rèn)?

我剛好在 Hacker News 看到 John Nagle (Nagle 算法的創(chuàng)始人)對 @alicemazzy 提到這個問題的評論。

本質(zhì)問題是延遲確認(rèn)。200 毫秒的“延遲確認(rèn)”是一個非常不好的主意,1985 年中,在伯利克(Berkeley)研究 BSD 的人實際上沒有真正明白這個問題。延遲確認(rèn)是應(yīng)用層對 200 毫秒內(nèi)是否響應(yīng)的一場賭博,但是即便每次它都賭輸了,TCP 仍在使用延遲確認(rèn)。

他繼續(xù)說到,確認(rèn)本身是很小并且消耗很低的,延遲確認(rèn)引起的問題可能比它解決的問題還要多。

不懂得 TCP 你就無法解決 TCP 問題

我曾經(jīng)也認(rèn)為,TCP 是一個相當(dāng)?shù)讓拥膯栴},我不需要明白。大多數(shù)時候你的確不需要明白。但是有的時候,當(dāng)你在實踐中遇到由于 TCP 算法引起的 bug 時,懂點 TCP 知識就變得非常重要了。(正如我們經(jīng)常在博客中討論的,許多事情都是這樣,比如系統(tǒng)調(diào)用和操作系統(tǒng):) )

延遲確認(rèn)及 TCP_NODELAY 的交互非常不好——這對任何語言實現(xiàn)的 HTTP 請求都有影響。你不需要很深入的去了解,成為系統(tǒng)程序?qū)<摇5橇私庖稽c TCP 是如何運作的,對我的工作的確大有裨益。通過對 TCP 的學(xué)習(xí),我才意識到這篇博客所描述的問題也許正好是我所熟悉的領(lǐng)域。我也一直在使用 strace,并且會一直使用下去。

責(zé)任編輯:何妍 來源: 伯樂在線
相關(guān)推薦

2021-08-04 07:47:19

HTTP網(wǎng)絡(luò)協(xié)議

2014-07-02 16:51:08

WOT2014高效技術(shù)團(tuán)隊

2020-04-01 17:50:02

Python編程語言

2018-09-25 16:31:35

維諦技術(shù)

2019-08-06 14:54:22

Hadoop數(shù)據(jù)集海量數(shù)據(jù)

2020-06-01 13:15:57

MySQL優(yōu)化查詢

2017-04-29 09:17:28

MySQL優(yōu)化器服務(wù)器

2020-10-26 08:34:18

知識體系普適性

2023-09-19 08:01:33

數(shù)據(jù)格式化程序

2017-12-07 15:28:36

2017-12-07 15:47:25

2012-12-26 09:25:32

2023-08-30 08:30:09

2017-01-18 09:42:11

Go

2017-01-09 12:57:21

Linux

2024-10-12 14:58:07

2021-07-30 09:32:55

JavaEquals

2017-10-11 15:50:18

光纖通信傳輸

2021-07-18 08:23:47

校招git編程

2021-03-01 07:34:42

Java泛型ArrayList
點贊
收藏

51CTO技術(shù)棧公眾號