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. Skynet Pomelo Erlang Elixir 的认识

    1.skynet pomelo(node.js) elixir(erlang) 周末研究总结 手游这两年发展来看,感觉对实时性要求越来越高,有同事在研究Elixir开发,google得知这东西是基于e ...

  2. AD10长方形通孔焊盘的画法

    1.点击工具栏中[放置焊盘]按钮 2.按键盘Tab键弹出[焊盘]对话框 3.设置[空洞信息]相关尺寸(根据自己所需实际设置) 这里左边的单选按钮选择“槽”,通孔尺寸输入20mil,长度为80mil,旋 ...

  3. ODAC (V9.5.15) 学习笔记(二十)大数据量获取处理

    ODAC获取数据的效率比较高,在Web程序中希望能够更快获取第一页的数据时,可以有几种方式: 1.在数据库中进行分页处理: 2.获取所有数据,只是快速返回第一页数据. 第一种方案对应用服务器资源消耗最 ...

  4. U3D中IOS平台泛型方法尽少使用

    U3D的IOS最小运行库use micro mscorlib是不包含泛型反射方法的,如FieldType.GetGenericArguments方法.所以尽量少用List而直接使用array. 另外请 ...

  5. SharePoint 2010中重置windows 活动目录(AD)域用户密码的WebPart(免费下载)

    由于SharePoint 2013推出不久,并非所有的企业都会升级到SharePoint 2013的,毕竟升级不是打打补丁这么简单,更多的企业还是使用Sharepoint 2010版本的,因此本人自行 ...

  6. 十七、EnterpriseFrameWork框架核心类库之Web控制器

    回<[开源]EnterpriseFrameWork框架系列文章索引> EFW框架源代码下载:http://pan.baidu.com/s/1qWJjo3U EFW框架中的WebContro ...

  7. ruby -- 基础学习(九)filename去除扩展名

         Rails -- filename去除扩展名 简单例子:params[:upload]['preview'].original_filename 的值为templateOne.html.er ...

  8. WhatFontIs - 字体百科全书,没有不认识的字体

    我敢肯定,我不是唯一一个曾经特别想知道图片上使用的某个字体,然后特别无奈的到字体网站大海捞针似的的找类似的字体.如今,一个强大的软件字体识别——WhatFontIs,让我们的生活更轻松. 您可能感兴趣 ...

  9. 自动化运维工具之 Ansible 介绍及安装使用

    一.初识Ansible 介绍: Absible 使用 模块(Modules)来定义配置任务.模块可以用标准脚本语言(Python,Bash,Ruby,等等)编写,这是一个很好的做法,使每个模块幂等.A ...

  10. 如何根据iframe内嵌页面调整iframe高宽续篇

    接着昨天的工作 如何根据iframe内嵌页面调整iframe高宽 来说,按照文章中说的第二种方法实现代码如下: 实现 A.com/detail/view 页面的iframe代码如下: <ifra ...