【TCP】socket的標準參數中:logback 參數配置方法

0 Backlog是什麼?

BACKLOG用於構造服務端套接字ServerSocket對象,標識當服務器請求處理線程全滿時,用於臨時存放已完成三次握手的請求的隊列的最大長度。如果未設置或所設置的值小於1,Java將使用默認值50。

1 Tomcat 配置(8.5.34版本)

   org.apache.coyote.AbstractProtocol中:org.apache.coyote.AbstractProtocol#setBacklog 和 org.apache.tomcat.util.net.AbstractEndpoint#setBacklog 已經廢棄,轉用org.apache.coyote.AbstractProtocol#setAcceptCount和org.apache.tomcat.util.net.AbstractEndpoint#setAcceptCount

   參數:org.apache.tomcat.util.net.AbstractEndpoint#acceptCount
   /**
     * Allows the server developer to specify the acceptCount (backlog) that
     * should be used for server sockets. By default, this value
     * is 100.
     */
    private int acceptCount = 100;
    public void setAcceptCount(int acceptCount) { if (acceptCount > 0) this.acceptCount = acceptCount; }

springboot 相關的配置,實現相關的接口即可:org.springframework.boot.web.embedded.tomcat.TomcatConnectorCustomizer

實現該接口:配置最大Send_Q隊列長度爲200

   @Override
        public void customize(Connector connector) {
            this.connector = connector;
            Http11NioProtocol protocolHandler = (Http11NioProtocol)connector.getProtocolHandler();
            protocolHandler.setAcceptCount(200);
        }

 

2 NIO server端配置

        // 最終由 min(backlog, /proc/sys/net/core/somaxconn) 決定Send_Q 大小
        // 默認50 此處配置成100 

        serverSocket.bind(new InetSocketAddress(port),100); 

    public NIOServer(int port) throws IOException {
        //開啓ServerSocketChannel
        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
        //設置爲非阻塞
        serverSocketChannel.configureBlocking(false);
        //獲取ServerSocket
        ServerSocket serverSocket = serverSocketChannel.socket();
        //綁定ServerSocket提供服務的端口
        // 最終由 min(backlog, /proc/sys/net/core/somaxconn) 決定Send_Q 大小
        // 默認50 此處配置成100 
        serverSocket.bind(new InetSocketAddress(port),100); 
        //開啓選擇器
        selector = Selector.open();
        //將ServerSocketChannel註冊到選擇器上
        serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
        System.out.println("NOIServer start run in port " + port);
    }

3 Netty 配置

        // BACKLOG用於構造服務端套接字ServerSocket對象,
        // 標識當服務器請求處理線程全滿時,用於臨時存放已完成三次握手的請求的隊列的最大長度
        bootstrap.option(ChannelOption.SO_BACKLOG, 1024);

public class NettyServer {
    /**
     * 端口
     */
    private int port;

    public NettyServer(int port) {
        this.port = port;
    }

    public void run() {
        //EventLoopGroup是用來處理IO操作的多線程事件循環器
        //負責接收客戶端連接線程
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        //負責處理客戶端i/o事件、task任務、監聽任務組
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        //啓動 NIO 服務的輔助啓動類
        ServerBootstrap bootstrap = new ServerBootstrap();
        bootstrap.group(bossGroup, workerGroup);
        //配置 Channel
        bootstrap.channel(NioServerSocketChannel.class);
        bootstrap.childHandler(new ServerIniterHandler());
        //BACKLOG用於構造服務端套接字ServerSocket對象,
        // 標識當服務器請求處理線程全滿時,用於臨時存放已完成三次握手的請求的隊列的最大長度
        bootstrap.option(ChannelOption.SO_BACKLOG, 1024);
        //是否啓用心跳保活機制
        bootstrap.childOption(ChannelOption.SO_KEEPALIVE, true);
        try {
            //綁定服務端口監聽
            Channel channel = bootstrap.bind(port).sync().channel();
            System.out.println("server run in port " + port);
            //服務器關閉監聽
            /*channel.closeFuture().sync()實際是如何工作:
            channel.closeFuture()不做任何操作,只是簡單的返回channel對象中的closeFuture對象,對於每個Channel對象,都會有唯一的一個CloseFuture,用來表示關閉的Future,
            所有執行channel.closeFuture().sync()就是執行的CloseFuturn的sync方法,從上面的解釋可以知道,這步是會將當前線程阻塞在CloseFuture上*/
            channel.closeFuture().sync();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            //關閉事件流組
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }
    }

    public static void main(String[] args) {
        new NettyServer(8899).run();
    }
}

4 其他Socket參數

      4.1 ChannelOption.SO_KEEPALIVE,  是否啓用心跳保活機制。在雙方TCP套接字建立連接後(即都進入ESTABLISHED狀態)並且在兩個小時左右(參考 https://blog.csdn.net/qfzhangwei/article/details/90614253#comments上層沒有任何數據傳輸的情況下,這套機制纔會被激活。

     4.2  ChannelOption.TCP_NODELAY,  在TCP/IP協議中,無論發送多少數據,總是要在數據前面加上協議頭,同時,對方接收到數據,也需要發送ACK表示確認。爲了儘可能的利用網絡帶寬,TCP總是希望儘可能的發送足夠大的數據。這裏就涉及到一個名爲Nagle的算法,該算法的目的就是爲了儘可能發送大塊數據,避免網絡中充斥着許多小數據塊。TCP_NODELAY就是用於啓用或關於Nagle算法。如果要求高實時性,有數據發送時就馬上發送,就將該選項設置爲true關閉Nagle算法;如果要減少發送次數減少網絡交互,就設置爲false等累積一定大小後再發送。默認爲false。

5 Netty 相關

       5.1 ChannelOption.SO_REUSEADDR, 允許啓動一個監聽服務器並捆綁其衆所周知端口,即使以前建立的將此端口用做他們的本地端口的連接仍存在。這通常是重啓監聽服務器時出現,若不設置此選項,則bind時將出錯。 SO_REUSEADDR允許在同一端口上啓動同一服務器的多個實例,只要每個實例捆綁一個不同的本地IP地址即可。對於TCP,我們根本不可能啓動捆綁相同IP地址和相同端口號的多個服務器。 SO_REUSEADDR允許單個進程捆綁同一端口到多個套接口上,只要每個捆綁指定不同的本地IP地址即可。這一般不用於TCP服務器。 SO_REUSEADDR允許完全重複的捆綁:當一個IP地址和端口綁定到某個套接口上時,還允許此IP地址和端口捆綁到另一個套接口上。一般來說,這個特性僅在支持多播的系統上纔有,而且只對UDP套接口而言(TCP不支持多播)

     5.2 ChannelOption.SO_RCVBUF AND ChannelOption.SO_SNDBUF 定義接收或者傳輸的系統緩衝區buf的大小,

     5.3 ChannelOption.ALLOCATOR Netty4使用對象池,重用緩衝區

           bootstrap.option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT);

          bootstrap.childOption(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT);

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章