【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);

你可能感兴趣的:(TCP,linux)