在Netty中经常会看到这样的代码:

ServerBootstrap b = new ServerBootstrap();

b.group(bossGroup, workerGroup)

.channel(NioServerSocketChannel.class)

.option(ChannelOption.SO_BACKLOG, 1024)

.childHandler(new ChildChannelHandler());

这里有一个SO_BACKLOG参数,本篇文章解释一下这个参数的具体用途。

TCP的连接队列

我们看一下TCP三次握手的过程:

当 client 通过 connect 向 server 发出 SYN 包时,client 会维护一个 socket 等待队列,而 server 会维护一个 SYN 队列;

此时进入半链接的状态,如果 socket 等待队列满了,server 则会丢弃,而 client 也会由此返回 connection time out;只要是 client 没有收到 SYN+ACK,3s 之后,client 会再次发送,如果依然没有收到,9s 之后会继续发送;

半连接 syn 队列的长度为 max(64, /proc/sys/net/ipv4/tcp_max_syn_backlog) 决定

当 server 收到 client 的 SYN 包后,会返回 SYN, ACK 的包加以确认,client 的 TCP 协议栈会唤醒 socket 等待队列,发出 connect 调用;

client 返回 ACK 的包后,server 会进入一个新的叫 accept 的队列,该队列的长度为 min(backlog, somaxconn),默认情况下,somaxconn 的值为 128,表示最多有 129 的 ESTAB 的连接等待 accept(),而 backlog 的值则由 int listen(int sockfd, int backlog) 中的第二个参数指定,listen 里面的 backlog 的含义请看这里。需要注意的是,一些 Linux 的发型版本可能存在对 somaxcon 错误 truncating 方式;

当 accept 队列满了之后,即使 client 继续向 server 发送 ACK 的包,也会不被相应,此时,server 通过 /proc/sys/net/ipv4/tcp_abort_on_overflow 来决定如何返回,0 表示直接丢丢弃该 ACK,1 表示发送 RST 通知 client;相应的,client 则会分别返回 read timeout 或者 connection reset by peer。上面说的只是些理论,如果服务器不及时的调用 accept(),当 queue 满了之后,服务器并不会按照理论所述,不再对 SYN 进行应答,返回 ETIMEDOUT。根据这篇文档的描述,实际情况并非如此,服务器会随机的忽略收到的 SYN,建立起来的连接数可以无限的增加,只不过客户端会遇到延时以及超时的情况。

可以看到,整个 TCP stack 有如下的两个 queue:

一个是 half open(syn queue) queue(max(tcp_max_syn_backlog, 64)),用来保存 SYN_SENT 以及 SYN_RECV 的信息,其大小通过/proc/sys/net/ipv4/tcp_max_syn_backlog指定,一般默认值是512,不过这个设置有效的前提是系统的syncookies功能被禁用。互联网常见的TCP SYN FLOOD恶意DOS攻击方式就是建立大量的半连接状态的请求,然后丢弃,导致syns queue不能保存其它正常的请求。。

另外一个是 accept queue(min(somaxconn, backlog)),保存全连接状态的请求,其大小通过/proc/sys/net/core/somaxconn指定,在使用listen函数时,内核会根据传入的backlog参数与系统参数somaxconn,取二者的较小值。

Netty中的backlog参数

查看EpollServerChannelConfig中的backlog参数:

private volatile int backlog = NetUtil.SOMAXCONN;

使用了NetUtil.SOMAXCONN变量的值,在NetUtil中查看:

SOMAXCONN = AccessController.doPrivileged(new PrivilegedAction() {

@Override

public Integer run() {

// Determine the default somaxconn (server socket backlog) value of the platform.

// The known defaults:

// - Windows NT Server 4.0+: 200

// - Linux and Mac OS X: 128

int somaxconn = PlatformDependent.isWindows() ? 200 : 128;

File file = new File("/proc/sys/net/core/somaxconn");

BufferedReader in = null;

try {

// file.exists() may throw a SecurityException if a SecurityManager is used, so execute it in the

// try / catch block.

// See https://github.com/netty/netty/issues/4936

if (file.exists()) {

in = new BufferedReader(new FileReader(file));

somaxconn = Integer.parseInt(in.readLine());

if (logger.isDebugEnabled()) {

logger.debug("{}: {}", file, somaxconn);

}

} else {

// Try to get from sysctl

Integer tmp = null;

if (SystemPropertyUtil.getBoolean("io.netty.net.somaxconn.trySysctl", false)) {

tmp = sysctlGetInt("kern.ipc.somaxconn");

if (tmp == null) {

tmp = sysctlGetInt("kern.ipc.soacceptqueue");

if (tmp != null) {

somaxconn = tmp;

}

} else {

somaxconn = tmp;

}

}

if (tmp == null) {

logger.debug("Failed to get SOMAXCONN from sysctl and file {}. Default: {}", file,

somaxconn);

}

}

} catch (Exception e) {

logger.debug("Failed to get SOMAXCONN from sysctl and file {}. Default: {}", file, somaxconn, e);

} finally {

if (in != null) {

try {

in.close();

} catch (Exception e) {

// Ignored.

}

}

}

return somaxconn;

}

});

可以看到,在默认情况下somaxconn的值为:

Windows NT Server 4.0+: 200

Linux and Mac OS X: 128

这里也通过/proc/sys/net/core/somaxconn文件来获取somaxconn的值。

上文中说到,内核会根据传入的backlog参数与系统参数somaxconn,取二者的较小值,所以,如果想扩大accept queue的大小,必须要同时调整这两个参数。

java nio so_backlog_TCP的连接队列与backlog参数相关推荐

  1. java nio 断开连接_浅尝Java NIO与Tomcat连接调优

    本文使用jdk1.8.0_45和spring boot 2.1.4.RELEASE 涉及源码都放在https://github.com/sabersword/Nio 前因 这周遇到一个连接断开的问题, ...

  2. java nio socket长连接_nio实现Socket长连接和心跳

    前段时间用bio方式,也就是传统io实现了socket的长连接和心跳,总觉着服务端开启多线程管理socket连接的方式过于消耗资源,数据并发的情况下可能会影响到性能,因此就尝试使用nio改进原来的代码 ...

  3. java nio socket长连接_netty学习实战—实现websocket长连接和socket之间进程通信

    netty学习-实现websocket长连接和socket之间通信 最近正在学习netty,跟着教程写了一个基于WebSocket的网页聊天室,对netty有了一定的了解,现在正好项目使用到长连接,选 ...

  4. TCP半连接队列和全连接队列(史上最全)

    TCP半连接队列和全连接队列 文章很长,建议收藏起来慢慢读! 总目录 博客园版 为您奉上珍贵的学习资源 : 免费赠送 :<尼恩Java面试宝典>持续更新+ 史上最全 + 面试必备 2000 ...

  5. JAVA NIO:NIO与OIO的对比以及Channel通道、Selector选择器、Buffer缓冲区的介绍 高并发

    文章目录 二 Java NIO (一)NIO对比OIO (二)概述三个核心组件 Channel通道 Selector选择器 Buffer缓冲区 (三)Buffer详解 1 Buffer类 2 四个属性 ...

  6. JAVA NIO:NIO与OIO的对比以及Channel通道、Selector选择器、Buffer缓冲区的介绍 //高并发

    文章目录 二 Java NIO (一)NIO对比OIO (二)概述三个核心组件 Channel通道 Selector选择器 Buffer缓冲区 (三)Buffer详解 1 Buffer类 2 四个属性 ...

  7. windows下客户端连接上马上会断开连接_浅尝Java NIO与Tomcat简单连接调优

    P本文使用jdk1.8.0_45spring boot 2.1.4.RELEASE 涉及源码都放在https://github.com/sabersword/Nio 前因 这周遇到一个连接断开的问题, ...

  8. java nio ssl_java连接MQTT+SSL服务器

    java用ssl加密方式连接mqtt服务器.其它ssl加密的也可以参考,SSLSocketFactory获取部分都是一样的.踩了很多坑,根据生成工具不同(openssl和keytool)以及秘钥文件编 ...

  9. java nio 强制关闭_Java NIO服务器:远程主机强迫关闭了一个现有的连接

    Java NIO聊天室 中,若客户端强制关闭,服务器会报"java.io.IOException: 远程主机强迫关闭了一个现有的连接.",并且服务器会在报错后停止运行,错误的意思就 ...

最新文章

  1. 【linux】error: stdio.h: No such file or directory
  2. 【Paper】2017_The distributed optimal consensus algorithms for general linear multi-agent systems
  3. 《python机器学习经典实例》Expected 2D array, got 1D array instead和Reshape your data either using array.问题(已解决)
  4. 关于Android的EditText焦点问题
  5. gitlab 删除分支_初识gitlab工作流
  6. c 语言中 %是什么运算符,C 语言基础----详解C中的运算符
  7. 岳云鹏:买128G手机仅112G可用!手机系统占用存储空间应厂商消化?
  8. ES6中的扩展运算符
  9. 【7】测试用例设计-等价类分析法
  10. [原创]c# 加解密通用类
  11. Python的Django框架中的URL配置与松耦合
  12. MFC用户界面设计 一
  13. 优化模型之指派问题(整数规划)
  14. IDM6.38使用教程 ——下载加速 百度云下载加速 捕获网页视频,音乐
  15. 网页端调用客户端的cs 程序
  16. AASM rule of scoring sleep stages using EEG signal
  17. 魅族20值得入手吗 魅族20参数配置
  18. 为什么国外服务器域名备案可以不进行?
  19. -Dmaven.multiModuleProjectDirectory system property is not set. Check $M2_HOME e
  20. React 所见即所得编辑器 Vditor

热门文章

  1. mysql学习笔记整理——my.ini配置文件
  2. 倪齐民加盟《青春风暴》 暗助任容萱脱困境_0
  3. 低频125KHz激励信号发送
  4. JAVA 中的设计模式(一)
  5. [WikiOI] 1.1.2 求和
  6. Xna中利用Slimdx绘制中文
  7. 利用K线的影线,就能分析现货白银走势?
  8. 【笑话】错发短信 ------ 在我们学校bbs看到的,挺有意思,哈哈
  9. 2017年2月17日
  10. 各种消除眼袋的小方法