日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學(xué)無(wú)先后,達(dá)者為師

網(wǎng)站首頁(yè) 編程語(yǔ)言 正文

Netty的SO_LINGER不要隨便用

作者:不識(shí)君的荒漠 更新時(shí)間: 2023-07-04 編程語(yǔ)言

SO_LINGER

SO_LINGER是一個(gè)Socket選項(xiàng),它決定一個(gè)Socket關(guān)閉時(shí)的行為,因此配在server端配置的時(shí)候使用childOption配置,該選項(xiàng)針對(duì)每個(gè)連接配置生效,而不是全局性的配置。

該配置主要在阻塞IO的關(guān)閉場(chǎng)景下用的更多,當(dāng)然,對(duì)于非阻塞式IO這個(gè)也是同樣可以使用的,畢竟是針對(duì)socket的關(guān)閉行為,但是實(shí)際意義有限。

該參數(shù)指定了關(guān)閉時(shí)的超時(shí)時(shí)間,當(dāng)SO_LINGER設(shè)置為0時(shí),表示禁用SO_LINGER,關(guān)閉Socket后立即返回,內(nèi)核丟棄套接字發(fā)送隊(duì)列中的數(shù)據(jù),并發(fā)送TCP RST。這種行為經(jīng)常被稱(chēng)為“硬關(guān)閉”。

當(dāng)SO_LINGER設(shè)置為非零正整數(shù)時(shí),當(dāng)Socket關(guān)閉時(shí)將等待所有數(shù)據(jù)都已發(fā)送或超時(shí)到達(dá)所指定的超時(shí)值。如果要發(fā)送的數(shù)據(jù)與指定的超時(shí)時(shí)間相比較,那么將立即返回。

在Netty中,SO_LINGER選項(xiàng)默認(rèn)設(shè)置為-1,它采用操作系統(tǒng)默認(rèn)行為。在大多數(shù)情況下,使用操作系統(tǒng)默認(rèn)行為即可,但在某些特殊情況下可能需要調(diào)整此選項(xiàng),例如在需要確保所有數(shù)據(jù)已經(jīng)發(fā)送的應(yīng)用程序中。

配置示例

        bootstrap = new ServerBootstrap().group(bossGroup, workerGroup)
                .channel(NettyUtils.nioOrEpollServerSocketChannel())
                .childOption(ChannelOption.SO_LINGER, -1)
                .childOption(NioChannelOption.SO_LINGER, -1)

如示例代碼,有兩種配置方式,使用ChannelOption.SO_LINGER或者NioChannelOption.SO_LINGER。
這兩種方式的主要區(qū)別在代碼:io.netty.channel.socket.nio.NioServerSocketChannel的內(nèi)部類(lèi):NioServerSocketChannelConfig有setOption方法:

        @Override
        public <T> boolean setOption(ChannelOption<T> option, T value) {
            if (PlatformDependent.javaVersion() >= 7 && option instanceof NioChannelOption) {
                return NioChannelOption.setOption(jdkChannel(), (NioChannelOption<T>) option, value);
            }
            return super.setOption(option, value);
        }

如果java版本大于等于7并且是NioChannelOption最終會(huì)調(diào)用jdk的設(shè)置方式。
實(shí)際上這個(gè)地方區(qū)別對(duì)于這個(gè)參數(shù)的配置結(jié)果都是一樣的,沒(méi)有區(qū)別,可以隨便選擇一種方式。

不建議使用

在非阻塞IO下,SO_LINGER選項(xiàng)的作用有限。因?yàn)樵诜亲枞鸌O中,寫(xiě)操作通常是異步的,即數(shù)據(jù)被發(fā)送到緩沖區(qū)后就會(huì)立即返回,不會(huì)等待數(shù)據(jù)被傳輸?shù)侥繕?biāo)機(jī)器。因此,關(guān)閉套接字時(shí)如果設(shè)置了SO_LINGER選項(xiàng),也不會(huì)等待所有未發(fā)送的數(shù)據(jù)發(fā)送完畢,因?yàn)橐呀?jīng)無(wú)法確保所有數(shù)據(jù)都被發(fā)送出去了。

在Netty中,如果設(shè)置了SO_LINGER選項(xiàng),在使用非阻塞IO時(shí)可能會(huì)導(dǎo)致套接字無(wú)法正確關(guān)閉,從而導(dǎo)致資源泄露。因此,在Netty中,我們通常不會(huì)使用SO_LINGER選項(xiàng),而是使用Netty提供的優(yōu)雅關(guān)閉機(jī)制,即調(diào)用Channel.close()方法并在關(guān)閉前等待所有數(shù)據(jù)發(fā)送完畢。

需要注意的是,在某些特殊情況下,SO_LINGER選項(xiàng)仍然有用。比如在使用TCP連接池等技術(shù)時(shí),可能會(huì)出現(xiàn)連接池中的連接狀態(tài)不同步的問(wèn)題,此時(shí)可能需要使用SO_LINGER選項(xiàng)來(lái)確保所有數(shù)據(jù)被發(fā)送完畢,從而避免數(shù)據(jù)丟失或者連接不同步的問(wèn)題。

注意事項(xiàng)

  1. SO_LINGER選項(xiàng)只對(duì)關(guān)閉套接字時(shí)的行為有影響,對(duì)于讀寫(xiě)操作沒(méi)有任何影響。
  2. SO_LINGER選項(xiàng)默認(rèn)是禁用的,如果要啟用需要手動(dòng)設(shè)置。
  3. SO_LINGER選項(xiàng)的值為-1時(shí),表示關(guān)閉套接字時(shí)將等待所有未發(fā)送的數(shù)據(jù)發(fā)送完畢,直到超時(shí)或數(shù)據(jù)全部發(fā)送完畢。
  4. SO_LINGER選項(xiàng)的值為0時(shí),表示關(guān)閉套接字時(shí)將立刻關(guān)閉套接字,已發(fā)送但未被確認(rèn)的數(shù)據(jù)將被丟棄。
  5. SO_LINGER選項(xiàng)的值大于0時(shí),表示關(guān)閉套接字時(shí)將等待指定的時(shí)間,以確保數(shù)據(jù)被發(fā)送完畢。
  6. 在使用SO_LINGER選項(xiàng)時(shí)需要注意超時(shí)時(shí)間的設(shè)置,避免出現(xiàn)無(wú)法關(guān)閉套接字的情況,從而導(dǎo)致資源泄漏。

原文鏈接:https://blog.csdn.net/x763795151/article/details/130114960

  • 上一篇:沒(méi)有了
  • 下一篇:沒(méi)有了
欄目分類(lèi)
最近更新