netty不同于socket,其上次API没有提供设置backlog的选项,而是依赖于操作系统的somaxconn和tcp_max_syn_backlog,对于不同OS或版本,该值不同,建议根据实际并发量针对性设置。

对于linux,可通过cat /proc/sys/net/core/somaxconn查看,如下所示:

[root@dev-server ~]# cat /proc/sys/net/core/somaxconn
128

其含义官方说的很清楚,是三次握手通过后等待被应用accept的数量,如下所示:

The behavior of the backlog argument on TCP sockets changed with Linux 2.2. Now it specifies the queue length for completely established sockets waiting to be accepted, instead of the number of incomplete connection requests. The maximum length of the queue for incomplete sockets can be set using/proc/sys/net/ipv4/tcp_max_syn_backlog. When syncookies are enabled there is no logical maximum length and this setting is ignored.

tcp_max_syn_backlog则是尚未完成握手的数量。

按照官方所述,可通过如下方式更改:

echo 2048 > /proc/sys/net/core/somaxconn

以下测试基于centos 6.6 x86-64,我们先看直接修改/proc/sys/net/core/somaxconn的效果。

[root@dev-server sbin]# cat /proc/sys/net/core/somaxconn
10

修改后,打开几个ssh窗口,如下:

[root@dev-server sbin]# netstat -ano | grep 22 | grep tcp | grep EST
tcp 0 0 192.168.146.128:22 192.168.146.1:8058 ESTABLISHED keepalive (4902.43/0/0)
tcp 0 0 192.168.146.128:22 192.168.146.1:8113 ESTABLISHED keepalive (4997.28/0/0)
tcp 0 0 192.168.146.128:22 192.168.146.1:8122 ESTABLISHED keepalive (5011.72/0/0)
tcp 0 0 192.168.146.128:22 192.168.146.1:8419 ESTABLISHED keepalive (5422.60/0/0)
tcp 0 0 192.168.146.128:22 192.168.146.1:8411 ESTABLISHED keepalive (5412.07/0/0)
tcp 0 0 192.168.146.128:22 192.168.146.1:8085 ESTABLISHED keepalive (4952.01/0/0)
tcp 0 0 192.168.146.128:22 192.168.146.1:8284 ESTABLISHED keepalive (5244.48/0/0)
tcp 0 0 192.168.146.128:22 192.168.146.1:8291 ESTABLISHED keepalive (5250.04/0/0)
tcp 0 0 192.168.146.128:22 192.168.146.1:7120 ESTABLISHED keepalive (3950.53/0/0)
tcp 0 0 192.168.146.128:22 192.168.146.1:8497 ESTABLISHED keepalive (5542.61/0/0)
tcp 0 0 192.168.146.128:22 192.168.146.1:8061 ESTABLISHED keepalive (4909.67/0/0)
tcp 0 0 192.168.146.128:22 192.168.146.1:8013 ESTABLISHED keepalive (4831.05/0/0)
tcp 0 0 192.168.146.128:22 192.168.146.1:8103 ESTABLISHED keepalive (4986.47/0/0)
tcp 0 0 192.168.146.128:22 192.168.146.1:8292 ESTABLISHED keepalive (5254.47/0/0)
tcp 0 52 192.168.146.128:22 192.168.146.1:8511 ESTABLISHED on (0.24/0/0)
tcp 0 0 192.168.146.128:22 192.168.146.1:8289 ESTABLISHED keepalive (5247.21/0/0)
[root@dev-server sbin]# netstat -ano | grep 22 | grep tcp | grep EST | wc -l
16

因为ssh连接数默认值的原因,一直没有生效,现在换成nginx。

用nginx作为服务器,ngnix默认连接1024个,我们将它改到2000,重启。

然后java发socket连接:

    public static void main(String[] args) throws InterruptedException {
List<Socket> list = new ArrayList<Socket>();
for(int i=0;i<2000;i++) {
try {
Socket socket = new Socket("192.168.146.128",80);
list.add(socket);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("连接已经全部建立");
Thread.sleep(1000000);
}

[root@dev-server sbin]# netstat -ano | grep 128:80 | grep tcp | egrep -e "EST|SYN" | wc -l
1035
[root@dev-server sbin]# netstat -ano | grep 128:80 | grep tcp | egrep -e "EST|SYN" | wc -l
1033
[root@dev-server sbin]# netstat -ano | grep 128:80 | grep tcp | egrep -e "EST|SYN" | wc -l
1033
[root@dev-server sbin]# netstat -ano | grep 128:80 | grep tcp | egrep -e "EST|SYN" | wc -l
1035
[root@dev-server sbin]# netstat -ano | grep 128:80 | grep tcp | egrep -e "EST|SYN" | wc -l
1033

[root@dev-server sbin]# netstat -ano | grep 128:80 | grep tcp | egrep -e "SYN" | wc -l
8
[root@dev-server sbin]# netstat -ano | grep 128:80 | grep tcp | egrep -e "SYN" | wc -l
8
[root@dev-server sbin]# netstat -ano | grep 128:80 | grep tcp | egrep -e "EST|SYN" | wc -l
1033
[root@dev-server sbin]# netstat -ano | grep 128:80 | grep tcp | egrep -e "EST|SYN" | wc -l
1033
[root@dev-server sbin]# netstat -ano | grep 128:80 | grep tcp | egrep -e "SYN" | wc -l
7
[root@dev-server sbin]# netstat -ano | grep 128:80 | grep tcp | egrep -e "SYN" | wc -l
8

在/etc/sysctl.conf中添加如下:

net.core.somaxconn = 100

sysctl -p即可。

[root@dev-server sbin]# netstat -ano | grep 128:80 | grep tcp | egrep -e "EST|SYN" | wc -l
0
[root@dev-server sbin]# netstat -ano | grep 128:80 | grep tcp | egrep -e "EST|SYN" | wc -l
200
[root@dev-server sbin]# netstat -ano | grep 128:80 | grep tcp | egrep -e "EST" | wc -l
200
[root@dev-server sbin]# netstat -ano | grep 128:80 | grep tcp | egrep -e "EST" | wc -l
1026
[root@dev-server sbin]# netstat -ano | grep 128:80 | grep tcp | egrep -e "EST|SYN" | wc -l
1034
[root@dev-server sbin]# netstat -ano | grep 128:80 | grep tcp | egrep -e "EST" | wc -l
1026
[root@dev-server sbin]# netstat -ano | grep 128:80 | grep tcp | egrep -e "EST|SYN" | wc -l
1035

最大连接数好像还是1024,somaxconn像是最大连接数的限制,当一个监听端口尝试建立的连接超过1024时,其他尚未被接受的连接状态会处于SYN_RECV状态,如下:

[root@dev-server sbin]# netstat -ano | grep 128:80 | grep tcp | egrep -e "SYN"
tcp 0 0 192.168.146.128:80 192.168.146.1:21131 SYN_RECV on (3.68/2/0)
tcp 0 0 192.168.146.128:80 192.168.146.1:21138 SYN_RECV on (0.30/0/0)
tcp 0 0 192.168.146.128:80 192.168.146.1:21133 SYN_RECV on (0.28/0/0)
tcp 0 0 192.168.146.128:80 192.168.146.1:21130 SYN_RECV on (0.68/2/0)
tcp 0 0 192.168.146.128:80 192.168.146.1:21122 SYN_RECV on (2.68/3/0)
tcp 0 0 192.168.146.128:80 192.168.146.1:21128 SYN_RECV on (0.88/2/0)
tcp 0 0 192.168.146.128:80 192.168.146.1:21132 SYN_RECV on (3.48/2/0)
tcp 0 0 192.168.146.128:80 192.168.146.1:21120 SYN_RECV on (0.08/3/0)

服务端收到建立连接的SYN、但没有收到ACK包或者没有发出SYNC+ACK的时候处在SYN_RECV状态。如下所示:

PS:上面这张图的关闭部分其实不是完全正确的,左边称为主动发起方、右边称为被动方才是正确的,因为作为发起者完全可以是server。

现在我们来看重启之后的情况:

[root@dev-server ~]# netstat -ano | grep 128:80 | grep tcp | egrep -e "EST|SY" | wc -l
1128
[root@dev-server ~]# netstat -ano | grep 128:80 | grep tcp | egrep -e "EST" | wc -l
1116
[root@dev-server ~]# netstat -ano | grep 128:80 | grep tcp | egrep -e "EST" | wc -l
1116
[root@dev-server ~]# netstat -ano | grep 128:80 | grep tcp | egrep -e "EST|SY" | wc -l
1134

可以发现,上下波动,基本上还是这个值左右。

现在增加看看,

[root@dev-server ~]# sysctl -p
net.ipv4.ip_forward = 0
net.ipv4.conf.default.rp_filter = 1
net.ipv4.conf.default.accept_source_route = 0
kernel.sysrq = 0
kernel.core_uses_pid = 1
net.ipv4.tcp_syncookies = 1
error: "net.bridge.bridge-nf-call-ip6tables" is an unknown key
error: "net.bridge.bridge-nf-call-iptables" is an unknown key
error: "net.bridge.bridge-nf-call-arptables" is an unknown key
kernel.msgmnb = 65536
kernel.msgmax = 65536
kernel.shmmax = 68719476736
kernel.shmall = 4294967296
net.core.somaxconn = 2000

[root@dev-server sbin]# netstat -ano | grep 128:80 | grep tcp | egrep -e "EST" | wc -l
1527
[root@dev-server sbin]# netstat -ano | grep 128:80 | grep tcp | egrep -e "EST" | wc -l
1527
[root@dev-server sbin]# netstat -ano | grep 128:80 | grep tcp | egrep -e "EST|SYN" | wc -l
1549
[root@dev-server sbin]# netstat -ano | grep 128:80 | grep tcp | egrep -e "EST|SYN" | wc -l
1555
[root@dev-server sbin]# netstat -ano | grep 128:80 | grep tcp | egrep -e "EST|SYN" | wc -l
1555
[root@dev-server sbin]# netstat -ano | grep 128:80 | grep tcp | egrep -e "EST|SYN" | wc -l
1555
[root@dev-server sbin]# netstat -ano | grep 128:80 | grep tcp | egrep -e "EST|SYN" | wc -l
1557
[root@dev-server sbin]# netstat -ano | grep 128:80 | grep tcp | egrep -e "EST|SYN" | wc -l
1557

可以发现,已经上来了,因为系统vmware配置原因还没有全部连接上来。

======

现在我们同时减少nginx和somaxconn的值,来看下:

nginx最大连接数设置100,somaxconn设置为200.

[root@dev-server conf]# netstat -ano | grep 128:80 | grep tcp | egrep -e "EST" | wc -l
76
[root@dev-server conf]# netstat -ano | grep 128:80 | grep tcp | egrep -e "EST" | wc -l
76
[root@dev-server conf]# netstat -ano | grep 128:80 | grep tcp | egrep -e "EST" | wc -l
88
[root@dev-server conf]# netstat -ano | grep 128:80 | grep tcp | egrep -e "EST" | wc -l
88
[root@dev-server conf]# netstat -ano | grep 128:80 | grep tcp | egrep -e "EST" | wc -l
88
[root@dev-server conf]# netstat -ano | grep 128:80 | grep tcp | egrep -e "EST" | wc -l

发现最大连接数同时受应用程序和somaxconn控制,应用小时取应用,应用大时取了1024。

因为用的是短连接测试,抽空再找时间测试下长连接的情况。

linux backlog深入剖析以及netty设置backlog的更多相关文章

  1. Tomcat 调优之从 Linux 内核源码层面看 Tcp backlog

    前两天看到一群里在讨论 Tomcat 参数调优,看到不止一个人说通过 accept-count 来配置线程池大小,我笑了笑,看来其实很多人并不太了解我们用的最多的 WebServer Tomcat,这 ...

  2. 【原创】Linux RCU原理剖析(二)-渐入佳境

    背景 Read the fucking source code! --By 鲁迅 A picture is worth a thousand words. --By 高尔基 说明: Kernel版本: ...

  3. Linux中文显示乱码?如何设置centos显示中文

    Linux中文显示乱码?如何设置centos显示中文 怎么设置Linux系统中文语言,这是很多小伙伴在开始使用Linux的时候,都会遇到一个问题,就是终端输入命令回显的时候中文显示乱码.出现这个情况一 ...

  4. hadoop搭建杂记:Linux下JDK环境变量的设置(三种配置环境变量的方法)

    Linux下JDK环境变量的设置(三种配置环境变量的方法) Linux下JDK环境变量的设置(三种配置环境变量的方法) ①修改/etc/profile文件 如果你的计算机仅仅作为开发使用时推荐使用这种 ...

  5. Linux 动态库剖析

    进程与 API 动态链接的共享库是 GNU/Linux® 的一个重要方面.该种库允许可执行文件在运行时动态访问外部函数,从而(通过在需要时才会引入函数的方式)减少它们对内存的总体占用.本文研究了创建和 ...

  6. c/c++ linux epoll系列3 利用epoll_wait设置timeout时间长度

    linux epoll系列3 利用epoll_wait设置timeout时间长度 epoll_wait函数的第四个参数可以设置,epoll_wait函数的等待时间(timeout时间长度). 例子1, ...

  7. Linux Linux下最大文件描述符设置

    Linux下最大文件描述符设置 by:授客 QQ:1033553122 1.   系统可打开最大文件描述符设置 查看系统可打开最大文件描述符 # cat /proc/sys/fs/file-max 6 ...

  8. linux下为目录和文件设置权限

    摘:linux下为目录和文件设置权限 分类: Linux2012-05-09 03:18 7456人阅读 评论(1) 收藏 举报 linuxwordpressweb数据库serverfile linu ...

  9. Linux系统运维笔记(三),设置IP和DNS

    Linux系统运维笔记(三),设置IP和DNS 手工配置静态的IP地址 也就是手工配置IP地址.子网掩码.网关和DNS. vi /etc/sysconfig/network-scripts/ifcfg ...

随机推荐

  1. CSS基础(七):z-index详解

    概念 z-index 属性设置元素的堆叠顺序.拥有更高堆叠顺序的元素总是会处于堆叠顺序较低的元素的前面. 层级关系的比较 1. 对于同级元素,默认(或position:static)情况下文档流后面的 ...

  2. Mvc 拼接Html 导出 Excel(服务器不用安装呦!支持2007以上版本)

    新公司,新接触,老方法,更实用. 之前接触过Webform,winfrom 的导出Excel方法 ,优点:省事.缺点:服务器必须安装Office 这几天做项目 和 大牛学习了一下 新的方法,自己加以总 ...

  3. log4j2配置

    在eclipse使用log4j2的时候遇到个问题: 我已经把log4j2.xml放到/src目录下了,而且设置从trace开始都打印到终端,但是我的程序里trace, info都不打印,到了error ...

  4. ODBC连接问题

    http://zhidao.baidu.com/link?url=EPEMTuGC1q5wWavZigWseoHOwRLvpHyAVsdIgMLspErJOUZMEepIICUnT9IdkPQlYTm ...

  5. ruby中字符的转换

    1.将表格名转成class名 classify "book_comments".classify => "BookComment"   2.class名转 ...

  6. 蓝凌OA二次开发手册

    1.蓝凌OA表单前端调用后台数据 一.后台存储过程: create procedure sp_test @ftext nvarchar(50) as begin select @ftext as '测 ...

  7. Docker练习例子:基于 VNCServer + noVNC 构建 Docker 桌面系统

    0. 安装docker 这一步略,网上有好多教程,一般出现装不上的原因,也就是网速问题了,这个我也很难帮你. 1. 下载指定的镜像images docker pull dorowu/ubuntu-de ...

  8. 如何对excel进行列查重

    学习了excel函数:countif.表达式:COUNTIF(数据区域,条件),作用:对数据区域内符合条件单元格计数 具体应用 在“姓名”(列A)后插入一列(列B),在B2单元格输入公式“=IF(CO ...

  9. Java -- 根据当前日期获取当前一周的所有日期

    Learn From:http://my.oschina.net/hermer/blog/151274 /** * 测试 * @param args */ public static void mai ...

  10. ubuntu14.04 编译安装gcc-5.3.0

    最近编译个源码,要求对C++14的支持了,就GCC的编译安装最新的5.3.0,整个过程以root用户进行. 1.下载GCC源码,属于事后文档整理,已经不知道从哪下载了. 2.解压:tar -zxvf ...