<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          被鵝廠面怕了!

          共 2136字,需瀏覽 5分鐘

           ·

          2021-06-13 14:24

          大家好,我是周末不休息的小林哥。

          上周有位讀者找我說,他在面試鵝廠的時(shí)候,遇到了這么個(gè)問題:

          這個(gè)屬于 TCP 異常斷開連接的場(chǎng)景,這部分內(nèi)容在我的「圖解網(wǎng)絡(luò)」還沒有詳細(xì)介紹過,這次就乘著這次機(jī)會(huì)補(bǔ)一補(bǔ)。

          這個(gè)問題有幾個(gè)關(guān)鍵詞:

          • 沒有開啟 keepalive;

          • 一直沒有數(shù)據(jù)交互;

          • 進(jìn)程崩潰;

          • 主機(jī)崩潰;

          我們先來認(rèn)識(shí)認(rèn)識(shí)什么是 TCP keepalive 呢?

          這東西其實(shí)就是 TCP 的保活機(jī)制,它的工作原理我之前的文章寫過,這里就直接貼下以前的內(nèi)容。

          如果兩端的 TCP 連接一直沒有數(shù)據(jù)交互,達(dá)到了觸發(fā) TCP 保活機(jī)制的條件,那么內(nèi)核里的 TCP 協(xié)議棧就會(huì)發(fā)送探測(cè)報(bào)文。

          • 如果對(duì)端程序是正常工作的。當(dāng) TCP 保活的探測(cè)報(bào)文發(fā)送給對(duì)端, 對(duì)端會(huì)正常響應(yīng),這樣 TCP 保活時(shí)間會(huì)被重置,等待下一個(gè) TCP 保活時(shí)間的到來。

          • 如果對(duì)端主機(jī)崩潰,或?qū)Χ擞捎谄渌驅(qū)е聢?bào)文不可達(dá)。當(dāng) TCP 保活的探測(cè)報(bào)文發(fā)送給對(duì)端后,石沉大海,沒有響應(yīng),連續(xù)幾次,達(dá)到保活探測(cè)次數(shù)后,TCP 會(huì)報(bào)告該 TCP 連接已經(jīng)死亡

          所以,TCP 保活機(jī)制可以在雙方?jīng)]有數(shù)據(jù)交互的情況,通過探測(cè)報(bào)文,來確定對(duì)方的 TCP 連接是否存活。

          注意,應(yīng)用程序若想使用 TCP 保活機(jī)制需要通過 socket 接口設(shè)置 SO_KEEPALIVE 選項(xiàng)才能夠生效,如果沒有設(shè)置,那么就無法使用 TCP 保活機(jī)制。

          知道了 TCP keepalive 作用,我們?cè)倩剡^頭看題目中的「主機(jī)崩潰」這種情況。

          在沒有開啟 TCP keepalive,且雙方一直沒有數(shù)據(jù)交互的情況下,如果客戶端的「主機(jī)崩潰」了,會(huì)發(fā)生什么。

          如果客戶端主機(jī)崩潰了,服務(wù)端是無法感知到的,在加上服務(wù)端沒有開啟 TCP keepalive,又沒有數(shù)據(jù)交互的情況下,服務(wù)端的 TCP 連接將會(huì)一直處于 ESTABLISHED 連接狀態(tài),直到服務(wù)端重啟進(jìn)程。

          所以,我們可以得知一個(gè)點(diǎn)。

          在沒有使用 TCP 保活機(jī)制,且雙方不傳輸數(shù)據(jù)的情況下,一方的 TCP 連接處在 ESTABLISHED 狀態(tài)時(shí),并不代表另一方的 TCP 連接還一定是正常的。

          那題目中的「進(jìn)程崩潰」的情況呢?

          我自己做了個(gè)實(shí)驗(yàn),使用 kill -9 來模擬進(jìn)程崩潰的情況,發(fā)現(xiàn)在 kill 掉進(jìn)程后,服務(wù)端會(huì)發(fā)送 FIN 報(bào)文,與客戶端進(jìn)行四次揮手

          所以,即使沒有開啟 TCP keepalive,且雙方也沒有數(shù)據(jù)交互的情況下,如果其中一方的進(jìn)程發(fā)生了崩潰,這個(gè)過程操作系統(tǒng)是可以感知的到的,于是就會(huì)發(fā)送 FIN 報(bào)文給對(duì)方,然后與對(duì)方進(jìn)行 TCP 四次揮手。

          以上就是對(duì)這個(gè)面試題的回答。

          這面試題其實(shí)在變相考察 TCP 保活機(jī)制的作用。


          接下來我們看看在有數(shù)據(jù)傳輸」的場(chǎng)景下的一些異常情況:

          • 第一種,客戶端主機(jī)宕機(jī),又迅速重啟,會(huì)發(fā)生什么?

          • 第二種,客戶端主機(jī)宕機(jī),一直沒有重啟,會(huì)發(fā)生什么?

          客戶端主機(jī)宕機(jī),又迅速重啟

          在客戶端主機(jī)宕機(jī)后,服務(wù)端向客戶端發(fā)送的報(bào)文會(huì)得不到任何的響應(yīng),在一定時(shí)長后,服務(wù)端就會(huì)觸發(fā)超時(shí)重傳機(jī)制,重傳未得到響應(yīng)的報(bào)文。

          服務(wù)端重傳報(bào)文的過程中,剛好客戶端主機(jī)重啟完成,這時(shí)客戶端的內(nèi)核就會(huì)接收重傳的報(bào)文,:

          • 如果客戶端主機(jī)上沒有進(jìn)程監(jiān)聽該 TCP 報(bào)文的目標(biāo)端口號(hào),由于找不到目標(biāo)端口,客戶端內(nèi)核就會(huì)回復(fù) RST 報(bào)文,重置該 TCP 連接

          • 如果客戶端主機(jī)上進(jìn)程監(jiān)聽該 TCP 報(bào)文的目標(biāo)端口號(hào),由于客戶端主機(jī)重啟后,之前的 TCP 連接的數(shù)據(jù)結(jié)構(gòu)已經(jīng)丟失了,客戶端內(nèi)核里協(xié)議棧會(huì)發(fā)現(xiàn)找不到該 TCP 連接的 socket 結(jié)構(gòu)體,于是就會(huì)回復(fù) RST 報(bào)文,重置該 TCP 連接。

          所以,只要有一方重啟完成后,收到之前 TCP 連接的報(bào)文,都會(huì)回復(fù) RST 報(bào)文,以斷開連接。

          客戶端主機(jī)宕機(jī),一直沒有重啟

          這種情況,服務(wù)端超時(shí)重傳報(bào)文的次數(shù)達(dá)到一定閾值后,內(nèi)核就會(huì)判定出該 TCP 有問題,然后通過 Socket 接口告訴應(yīng)用程序該 TCP 連接出問題了。

          那具體重傳幾次呢?

          在 Linux 系統(tǒng)中,提供了一個(gè)叫 tcp_retries2 配置項(xiàng),默認(rèn)值是 15,如下圖:

          這個(gè)內(nèi)核參數(shù)是控制,在 TCP 連接建立的情況下,超時(shí)重傳的最大次數(shù)。

          不過 tcp_retries2 設(shè)置了 15 次,并不代表 TCP 超時(shí)重傳了 15 次才會(huì)通知應(yīng)用程序終止該 TCP 連接,內(nèi)核還會(huì)基于「最大超時(shí)時(shí)間」來判定。

          每一輪的超時(shí)時(shí)間都是倍數(shù)增長的,比如第一次觸發(fā)超時(shí)重傳是在 2s 后,第二次則是在 4s 后,第三次則是 8s 后,以此類推。

          內(nèi)核會(huì)根據(jù) tcp_retries2 設(shè)置的值,計(jì)算出一個(gè)最大超時(shí)時(shí)間。

          在重傳報(bào)文且一直沒有收到對(duì)方響應(yīng)的情況時(shí),先達(dá)到「最大重傳次數(shù)」或者「最大超時(shí)時(shí)間」這兩個(gè)的其中一個(gè)條件后,就會(huì)停止重傳


          最后說句。

          TCP 牛逼,啥異常都考慮到了

          瀏覽 52
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  中文字幕一区二区久久人妻网站 | 观看操逼视频 | 久久免费美女操B视频 | 思思热99在线 | 青青青青操 |