linux backlog深入剖析以及netty设置backlog
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的更多相关文章
- Tomcat 调优之从 Linux 内核源码层面看 Tcp backlog
前两天看到一群里在讨论 Tomcat 参数调优,看到不止一个人说通过 accept-count 来配置线程池大小,我笑了笑,看来其实很多人并不太了解我们用的最多的 WebServer Tomcat,这 ...
- 【原创】Linux RCU原理剖析(二)-渐入佳境
背景 Read the fucking source code! --By 鲁迅 A picture is worth a thousand words. --By 高尔基 说明: Kernel版本: ...
- Linux中文显示乱码?如何设置centos显示中文
Linux中文显示乱码?如何设置centos显示中文 怎么设置Linux系统中文语言,这是很多小伙伴在开始使用Linux的时候,都会遇到一个问题,就是终端输入命令回显的时候中文显示乱码.出现这个情况一 ...
- hadoop搭建杂记:Linux下JDK环境变量的设置(三种配置环境变量的方法)
Linux下JDK环境变量的设置(三种配置环境变量的方法) Linux下JDK环境变量的设置(三种配置环境变量的方法) ①修改/etc/profile文件 如果你的计算机仅仅作为开发使用时推荐使用这种 ...
- Linux 动态库剖析
进程与 API 动态链接的共享库是 GNU/Linux® 的一个重要方面.该种库允许可执行文件在运行时动态访问外部函数,从而(通过在需要时才会引入函数的方式)减少它们对内存的总体占用.本文研究了创建和 ...
- c/c++ linux epoll系列3 利用epoll_wait设置timeout时间长度
linux epoll系列3 利用epoll_wait设置timeout时间长度 epoll_wait函数的第四个参数可以设置,epoll_wait函数的等待时间(timeout时间长度). 例子1, ...
- Linux Linux下最大文件描述符设置
Linux下最大文件描述符设置 by:授客 QQ:1033553122 1. 系统可打开最大文件描述符设置 查看系统可打开最大文件描述符 # cat /proc/sys/fs/file-max 6 ...
- linux下为目录和文件设置权限
摘:linux下为目录和文件设置权限 分类: Linux2012-05-09 03:18 7456人阅读 评论(1) 收藏 举报 linuxwordpressweb数据库serverfile linu ...
- Linux系统运维笔记(三),设置IP和DNS
Linux系统运维笔记(三),设置IP和DNS 手工配置静态的IP地址 也就是手工配置IP地址.子网掩码.网关和DNS. vi /etc/sysconfig/network-scripts/ifcfg ...
随机推荐
- Windows下移动MariaDB数据目录 (转!)
Windows下移动MariaDB数据目录: http://www.xue163.com/news/940/9403312.html [环境]OS:Windows Server 2008 R2 x64 ...
- [翻译]使用Swift在Xcode中创建自定义控件
使用Swift在Xcode中创建自定义控件 原文 IBDesignable and IBInspectable With IBDesignable and IBInspectable, develop ...
- Dennis与Ken爷爷的UNIX/C世界
沉寂了很久了,时间在不断地逝去,转眼又到了新的一年,2013的发生了太多,Beta版本.辞职.职位转换.ARM.Driver.初级厨艺.Dx11.GPU.CPU.登山.GNU/Linux.Cross ...
- Codeforces Round #195 A B C 三题合集 (Div. 2)
A 题 Vasily the Bear and Triangle 题目大意 一个等腰直角三角形 ABC,角 ACB 是直角,AC=BC,点 C 在原点,让确定 A 和 B 的坐标,使得三角形包含一个矩 ...
- web通过ActiveX打印
最近做了一个activex控件,可以通过html页面动态设置报表文件的数据,控件里的报表是通过FastReport实现了,可以通过FastReport先把报表设置好.欢迎大家提意见 控件及Demo下载
- 学习Sass之安装Sass(一)
为什么使用Sass 作为前端(html.javascript.css)的三大马车之一的css,一直以静态语言存在,HTML5火遍大江南北了.javascript由于NODE.JS而成为目前前后端统一开 ...
- VPN理论简单介绍(转载)
标签:VPN理论简单介绍 原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://lvnian.blog.51cto.com/715528 ...
- java攻城狮之路(Android篇)--SQLite
一.Junit 1.怎么使用 在AndroidManifest.xml文件中进行配置, 在manifest借点下配置instrumentation, 在application借点下 ...
- Android应用安全之Content Provider安全
android平台提供了Content Provider,将一个应用程序的指定数据集提供给其它应用程序.这些数据可以存储在文件系统.SQLite数据库中,或以任何其它合理的方式存储.其他应用可以通过C ...
- @media 手机与IPAD与PC
@media screen and (min-width: 769px) { bindCard{height:28.5em} } @media screen and (min-device-width ...