zoukankan      html  css  js  c++  java
  • Netty之ChannelOption的各种参数

    • ChannelOption.SO_BACKLOG, 1024

           BACKLOG用于构造服务端套接字ServerSocket对象,标识当服务器请求处理线程全满时,用于临时存放已完成三次握手的请求的队列的最大长度。如果未设置或所设置的值小于1,Java将使用默认值50。

      ChannelOption.SO_BACKLOG对应的是tcp/ip协议listen函数中的backlog参数,函数listen(int socketfd,int backlog)用来初始化服务端可连接队列,

        服务端处理客户端连接请求是顺序处理的,所以同一时间只能处理一个客户端连接,多个客户端来的时候,服务端将不能处理的客户端连接请求放在队列中等待处理,backlog参数指定了队列的大小

    • ChannelOption.SO_KEEPALIVE, true

          是否启用心跳保活机制。在双方TCP套接字建立连接后(即都进入ESTABLISHED状态)并且在两个小时左右上层没有任何数据传输的情况下,这套机制才会被激活。

    • ChannelOption.TCP_NODELAY, true

     在TCP/IP协议中,无论发送多少数据,总是要在数据前面加上协议头,同时,对方接收到数据,也需要发送ACK表示确认。为了尽可能的利用网络带宽,TCP总是希望尽可能的发送足够大的数据。这里就涉及到一个名为Nagle的算法,该算法的目的就是为了尽可能发送大块数据,避免网络中充斥着许多小数据块。

     TCP_NODELAY就是用于启用或关于Nagle算法。如果要求高实时性,有数据发送时就马上发送,就将该选项设置为true关闭Nagle算法;如果要减少发送次数减少网络交互,就设置为false等累积一定大小后再发送。默认为false。

    ChannelOption.TCP_NODELAY参数对应于套接字选项中的TCP_NODELAY,该参数的使用与Nagle算法有关

        Nagle算法是将小的数据包组装为更大的帧然后进行发送,而不是输入一次发送一次,因此在数据包不足的时候会等待其他数据的到了,组装成大的数据包进行发送,虽然该方式有效提高网络的有效

        负载,但是却造成了延时,而该参数的作用就是禁止使用Nagle算法,使用于小数据即时传输,于TCP_NODELAY相对应的是TCP_CORK,该选项是需要等到发送的数据量最大的时候,一次性发送

        数据,适用于文件传输。

    4.ChannelOption.SO_REUSEADDR, true

    SO_REUSEADDR允许启动一个监听服务器并捆绑其众所周知端口,即使以前建立的将此端口用做他们的本地端口的连接仍存在。这通常是重启监听服务器时出现,若不设置此选项,则bind时将出错。
    SO_REUSEADDR允许在同一端口上启动同一服务器的多个实例,只要每个实例捆绑一个不同的本地IP地址即可。对于TCP,我们根本不可能启动捆绑相同IP地址和相同端口号的多个服务器。
    SO_REUSEADDR允许单个进程捆绑同一端口到多个套接口上,只要每个捆绑指定不同的本地IP地址即可。这一般不用于TCP服务器。
    SO_REUSEADDR允许完全重复的捆绑:当一个IP地址和端口绑定到某个套接口上时,还允许此IP地址和端口捆绑到另一个套接口上。一般来说,这个特性仅在支持多播的系统上才有,而且只对UDP套接口而言(TCP不支持多播)

    5.ChannelOption.SO_RCVBUF AND ChannelOption.SO_SNDBUF
    定义接收或者传输的系统缓冲区buf的大小,

    6.ChannelOption.ALLOCATOR
    Netty4使用对象池,重用缓冲区
    bootstrap.option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT);
    bootstrap.childOption(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT);

    4.EpollChannelOption.SO_REUSEPORT, true


     前几天一个技术群里的小伙伴,

       问netty中.childOption(ChannelOption.SO_RCVBUF,  XX) 

        设置了没有效果, 抓包显示TCP的滑动窗口依然我行我素:) 
        我把我当时的回答再稍加修饰润色一下: 

        第一个误区就是: 

        TCP在三次握手建立连接期间就会通过ACK分组通告自己的初始接收窗口(通告窗口)大小,

       而上边的代码是netty在连接建立成功后才设置的, 所以必然是无效的设置, 

      正确的方法是设置到ServerSocket上, 也就是Option(Option.SO_RCVBUF, XX), 

      一个连接被ServerSocket accept后会clone一个此连接对应的socket, 这个值会继承过来. 

    
    

        还有一个误区就是: 

       其实并不是rcv_buf设置多大, 通告窗口就多大的, 他们之间有非比寻常的关系, 

        但绝对不是一一对应的关系, TCP是一种慢启动的协议, linux2.6.39版本之前, 

        在以太网环境中初始通告窗口是的3个MSS(MSS即最大的segment size, 以太网环境中是1460个字 

    
        节)然后根据拥塞避免算法一点一点增加, 3.x内核初始通告窗口是直接在代码中写死的10个MSS 
        (是google一篇论文的建议). 

        第三点是,

         我担心有人会这么想, 强调下recv_buf并不是个数组啥的(内核buf的数据结构大致是 

    
        一个segment queue), 也不会预先分配内存, 只是个接收缓冲区size的最大限制, 对端不给 
        你发数据, 内核不会自作多情分配内存给你, 要不然现在动辄单机上百万个长连接就是痴人说梦 
        了 

        总结: 通常情况下, 我个人经验是不建议设置rcv_buf, linux内核会对每一个连接做动态的 
        调整, 一般情况下足够智能, 如果设置死了, 就失去了这个特性, 尤其是大量长连接的应用, 
        我觉得这个设置就忘记吧, 要调优, 也最好到linux内核里面去配置对应参数. 


    2.6.32内核代码(/net/ipv4/tcp_input.c): 




    2.6.39内核代码(/net/ipv4/tcp_input.c, /include/net/tcp.h): 






    
    
  • 相关阅读:
    聊聊WS-Federation
    用双十一的故事串起碎片的网络协议(上)
    责任链模式的使用-Netty ChannelPipeline和Mina IoFilterChain分析
    最小化局部边际的合并聚类算法(中篇)
    最小化局部边际的合并聚类算法(上篇)
    UVaLive 7371 Triangle (水题,判矩形)
    UVaLive 7372 Excellence (水题,贪心)
    POJ 3312 Mahershalalhashbaz, Nebuchadnezzar, and Billy Bob Benjamin Go to the Regionals (水题,贪心)
    UVa 1252 Twenty Questions (状压DP+记忆化搜索)
    UVa 10817 Headmaster's Headache (状压DP+记忆化搜索)
  • 原文地址:https://www.cnblogs.com/heroinss/p/9900762.html
Copyright © 2011-2022 走看看