TCP的連接隊(duì)列與backlog參數(shù)

在Netty中經(jīng)常會(huì)看到這樣的代碼:

ServerBootstrap b = new ServerBootstrap();
b.group(bossGroup, workerGroup)
        .channel(NioServerSocketChannel.class)
        .option(ChannelOption.SO_BACKLOG, 1024)
        .childHandler(new ChildChannelHandler());

這里有一個(gè)SO_BACKLOG參數(shù)像云,本篇文章解釋一下這個(gè)參數(shù)的具體用途庵楷。

TCP的連接隊(duì)列

我們看一下TCP三次握手的過程:

  1. 當(dāng) client 通過 connect 向 server 發(fā)出 SYN 包時(shí)暇藏,client 會(huì)維護(hù)一個(gè) socket 等待隊(duì)列洽胶,而 server 會(huì)維護(hù)一個(gè) SYN 隊(duì)列塔橡;
  2. 此時(shí)進(jìn)入半鏈接的狀態(tài)图焰,如果 socket 等待隊(duì)列滿了忌卤,server 則會(huì)丟棄,而 client 也會(huì)由此返回 connection time out楞泼;只要是 client 沒有收到 SYN+ACK驰徊,3s 之后笤闯,client 會(huì)再次發(fā)送,如果依然沒有收到棍厂,9s 之后會(huì)繼續(xù)發(fā)送颗味;
  3. 半連接 syn 隊(duì)列的長度為 max(64, /proc/sys/net/ipv4/tcp_max_syn_backlog) 決定
  4. 當(dāng) server 收到 client 的 SYN 包后,會(huì)返回 SYN, ACK 的包加以確認(rèn)牺弹,client 的 TCP 協(xié)議棧會(huì)喚醒 socket 等待隊(duì)列浦马,發(fā)出 connect 調(diào)用;
  5. client 返回 ACK 的包后张漂,server 會(huì)進(jìn)入一個(gè)新的叫 accept 的隊(duì)列晶默,該隊(duì)列的長度為 min(backlog, somaxconn),默認(rèn)情況下航攒,somaxconn 的值為 128磺陡,表示最多有 129 的 ESTAB 的連接等待 accept(),而 backlog 的值則由 int listen(int sockfd, int backlog) 中的第二個(gè)參數(shù)指定漠畜,listen 里面的 backlog 的含義請看這里币他。需要注意的是,一些 Linux 的發(fā)型版本可能存在對 somaxcon 錯(cuò)誤 truncating 方式憔狞;
  6. 當(dāng) accept 隊(duì)列滿了之后蝴悉,即使 client 繼續(xù)向 server 發(fā)送 ACK 的包,也會(huì)不被相應(yīng)瘾敢,此時(shí)肛度,server 通過 /proc/sys/net/ipv4/tcp_abort_on_overflow 來決定如何返回施无,0 表示直接丟丟棄該 ACK,1 表示發(fā)送 RST 通知 client;相應(yīng)的蔚舀,client 則會(huì)分別返回 read timeout 或者 connection reset by peer放吩。上面說的只是些理論乍炉,如果服務(wù)器不及時(shí)的調(diào)用 accept()替饿,當(dāng) queue 滿了之后,服務(wù)器并不會(huì)按照理論所述焦履,不再對 SYN 進(jìn)行應(yīng)答拓劝,返回 ETIMEDOUT。根據(jù)這篇文檔的描述嘉裤,實(shí)際情況并非如此郑临,服務(wù)器會(huì)隨機(jī)的忽略收到的 SYN,建立起來的連接數(shù)可以無限的增加屑宠,只不過客戶端會(huì)遇到延時(shí)以及超時(shí)的情況厢洞。

可以看到,整個(gè) TCP stack 有如下的兩個(gè) queue:

  1. 一個(gè)是 half open(syn queue) queue(max(tcp_max_syn_backlog, 64)),用來保存 SYN_SENT 以及 SYN_RECV 的信息躺翻,其大小通過/proc/sys/net/ipv4/tcp_max_syn_backlog指定丧叽,一般默認(rèn)值是512,不過這個(gè)設(shè)置有效的前提是系統(tǒng)的syncookies功能被禁用公你∮淮荆互聯(lián)網(wǎng)常見的TCP SYN FLOOD惡意DOS攻擊方式就是建立大量的半連接狀態(tài)的請求,然后丟棄陕靠,導(dǎo)致syns queue不能保存其它正常的請求迂尝。。
  2. 另外一個(gè)是 accept queue(min(somaxconn, backlog))剪芥,保存全連接狀態(tài)的請求垄开,其大小通過/proc/sys/net/core/somaxconn指定,在使用listen函數(shù)時(shí)税肪,內(nèi)核會(huì)根據(jù)傳入的backlog參數(shù)與系統(tǒng)參數(shù)somaxconn溉躲,取二者的較小值。

Netty中的backlog參數(shù)

查看EpollServerChannelConfig中的backlog參數(shù):

private volatile int backlog = NetUtil.SOMAXCONN;

使用了NetUtil.SOMAXCONN變量的值寸认,在NetUtil中查看:

SOMAXCONN = AccessController.doPrivileged(new PrivilegedAction<Integer>() {
    @Override
    public Integer run() {
        // Determine the default somaxconn (server socket backlog) value of the platform.
        // The known defaults:
        // - Windows NT Server 4.0+: 200
        // - Linux and Mac OS X: 128
        int somaxconn = PlatformDependent.isWindows() ? 200 : 128;
        File file = new File("/proc/sys/net/core/somaxconn");
        BufferedReader in = null;
        try {
            // file.exists() may throw a SecurityException if a SecurityManager is used, so execute it in the
            // try / catch block.
            // See https://github.com/netty/netty/issues/4936
            if (file.exists()) {
                in = new BufferedReader(new FileReader(file));
                somaxconn = Integer.parseInt(in.readLine());
                if (logger.isDebugEnabled()) {
                    logger.debug("{}: {}", file, somaxconn);
                }
            } else {
                // Try to get from sysctl
                Integer tmp = null;
                if (SystemPropertyUtil.getBoolean("io.netty.net.somaxconn.trySysctl", false)) {
                    tmp = sysctlGetInt("kern.ipc.somaxconn");
                    if (tmp == null) {
                        tmp = sysctlGetInt("kern.ipc.soacceptqueue");
                        if (tmp != null) {
                            somaxconn = tmp;
                        }
                    } else {
                        somaxconn = tmp;
                    }
                }

                if (tmp == null) {
                    logger.debug("Failed to get SOMAXCONN from sysctl and file {}. Default: {}", file,
                                 somaxconn);
                }
            }
        } catch (Exception e) {
            logger.debug("Failed to get SOMAXCONN from sysctl and file {}. Default: {}", file, somaxconn, e);
        } finally {
            if (in != null) {
                try {
                    in.close();
                } catch (Exception e) {
                    // Ignored.
                }
            }
        }
        return somaxconn;
    }
});

可以看到,在默認(rèn)情況下somaxconn的值為:

  • Windows NT Server 4.0+: 200
  • Linux and Mac OS X: 128

這里也通過/proc/sys/net/core/somaxconn文件來獲取somaxconn的值串慰。

上文中說到偏塞,內(nèi)核會(huì)根據(jù)傳入的backlog參數(shù)與系統(tǒng)參數(shù)somaxconn,取二者的較小值邦鲫,所以灸叼,如果想擴(kuò)大accept queue的大小,必須要同時(shí)調(diào)整這兩個(gè)參數(shù)庆捺。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末古今,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子滔以,更是在濱河造成了極大的恐慌捉腥,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,743評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件你画,死亡現(xiàn)場離奇詭異抵碟,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)坏匪,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,296評論 3 385
  • 文/潘曉璐 我一進(jìn)店門拟逮,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人适滓,你說我怎么就攤上這事敦迄。” “怎么了?”我有些...
    開封第一講書人閱讀 157,285評論 0 348
  • 文/不壞的土叔 我叫張陵罚屋,是天一觀的道長苦囱。 經(jīng)常有香客問我,道長沿后,這世上最難降的妖魔是什么沿彭? 我笑而不...
    開封第一講書人閱讀 56,485評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮尖滚,結(jié)果婚禮上喉刘,老公的妹妹穿的比我還像新娘。我一直安慰自己漆弄,他們只是感情好睦裳,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,581評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著撼唾,像睡著了一般廉邑。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上倒谷,一...
    開封第一講書人閱讀 49,821評論 1 290
  • 那天蛛蒙,我揣著相機(jī)與錄音,去河邊找鬼渤愁。 笑死牵祟,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的抖格。 我是一名探鬼主播诺苹,決...
    沈念sama閱讀 38,960評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼雹拄!你這毒婦竟也來了收奔?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,719評論 0 266
  • 序言:老撾萬榮一對情侶失蹤滓玖,失蹤者是張志新(化名)和其女友劉穎坪哄,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體势篡,經(jīng)...
    沈念sama閱讀 44,186評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡损姜,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,516評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了殊霞。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片摧阅。...
    茶點(diǎn)故事閱讀 38,650評論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖绷蹲,靈堂內(nèi)的尸體忽然破棺而出棒卷,到底是詐尸還是另有隱情顾孽,我是刑警寧澤,帶...
    沈念sama閱讀 34,329評論 4 330
  • 正文 年R本政府宣布比规,位于F島的核電站若厚,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏蜒什。R本人自食惡果不足惜测秸,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,936評論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望灾常。 院中可真熱鬧霎冯,春花似錦、人聲如沸钞瀑。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,757評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽雕什。三九已至缠俺,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間贷岸,已是汗流浹背壹士。 一陣腳步聲響...
    開封第一講書人閱讀 31,991評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留偿警,地道東北人躏救。 一個(gè)月前我還...
    沈念sama閱讀 46,370評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像户敬,于是被迫代替她去往敵國和親落剪。 傳聞我的和親對象是個(gè)殘疾皇子睁本,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,527評論 2 349

推薦閱讀更多精彩內(nèi)容