SO_RCVBUF

适用于TCP和UDP socket接收缓冲区,该值会影响应用程序的吞吐量

  • UDP协议的话,对丢包有很大的帮助,不过设置过大,也会雪崩,程序处理不过来,多大的rcvbuf都不够用
  • SO_RCVBUF的大小受制于操作系统的限制,这个很容易理解,就是操作系统 要作为保护系统的最后一道屏障,得有一个阀值来控制极其不合理的设置,具体查看Linux内核参数net.core.rmem_max和net.core.wmem_default.例如:如果我们设置的 SO_RCVBUF大于net.core.rmem_max,就会取net.core.rmem_max为最终结果
SO_SNDBUF

适用于TCP和UDP socket发送缓冲区,该值会影响应用程序的吞吐量

  • 具体细节可以参考SO_RCVBUF的说明,他们两个一个接收,一个发送,注意点都是相同的,Linux内核参数配置为net.core.wmem_max和net.core.wmem_default
TCP_NODELAY

适用于TCP

  • TCP_NODELAY=TRUE 则禁用Nagle算法
  • Nagle算法是以减少数据包发送量来增进TCP/IP网络的性能

RCVBUF_ALLOCATOR

适用于TCP,UDP, netty从socket缓冲区每次读取收据的大小,受制于该配置

  • 实现类有FixedRecvByteBufAllocator和AdaptiveRecvByteBufAllocator,尽量使用AdaptiveRecvByteBufAllocator,因为AdaptiveRecvByteBufAllocator作为自适应接收缓冲区内存分配的实现,可以根据上次接收到的数据大小,来自己调整下次应该分配的空间,这样可以节省内存,特别是连接比较多的应用
  • 对于UDP,如果RCVBUF_ALLOCATOR的缓冲区大小,小于发送端消息的大小,就会造成消息被截断,所以该配置的大小要合理设置
  • DefaultMaxMessagesRecvByteBufAllocator.maxMessagesPerRead
  • netty每次收到socket read通知,读取maxMessagesPerRead条数据(最多,没有足够的则返回),具体查看逻辑io.netty.channel.DefaultMaxMessagesRecvByteBufAllocator.MaxMessageHandle#continueReading(io.netty.util.UncheckedBooleanSupplier)
  • 默认情况下,socket通知应用程序缓冲区有新数据,应用程序就会去读取一条,循环往复,netty内部可以设置maxMessagesPerRead,来一次性读取多条数据,来提高一定的性能,默认maxMessagesPerRead=0,也就是读取一次
  • 设置maxMessagesPerRead时要注意,如果你使用的是AdaptiveRecvByteBufAllocator,那么udp下,有可能是存在消息被截取的情况,后边说明该情况
  • 建议:最好不要去设置该参数,除非你很了解netty
  • DefaultMaxMessagesRecvByteBufAllocator.respectMaybeMoreData
  • 该配置是配合maxMessagesPerRead来使用的,也就是只有maxMessagesPerRead>1的情况下,respectMaybeMoreData才起到作用
  • 这是为了防止,一次socket通知读取多条数据时,第一天以后数据被截取(因为第二条以后的数据读取大小,是以读取第一条数据时分配的大小为准的,当然FixedRecvByteBufAllocator是不受影响的,因为FixedRecvByteBufAllocator每次分配的大小是固定的)
  • 下边是复现一个有问题的案例
  • recvByteBufAllocator = new AdaptiveRecvByteBufAllocator(256, 500, 2048);//第一次会分配512字节的内存
  • recvByteBufAllocator.maxMessagesPerRead(3);//一次性尝试读取3条数据
  • recvByteBufAllocator.respectMaybeMoreData(false);//不关注后续消息可能会更大(相比第一条)
  • udpClient.send(200);udpClient.send(>512 bytes);//第一次发送200字节,第二次发送大于512字节
  • 其中,第二条数据收到的是512字节,而不是实际字节大小,具体可查看io.netty.channel.nio.AbstractNioMessageChannel.NioMessageUnsafe#read方法里面读取的逻辑
SO_KEEPALIVE
  • 参考 TCP持久连接
SO_TIMEOUT
  • 参考socket time out 理解