通过调整Linux的TCP链接限制数实现性能的优化
最近因为测试机器人,开了几千个机器人后发现因为服务器有tcp最大连接数限制,导致连接数达到一定数量后就会出现连接不上或者断线的问题,查阅资料后发现可以通过修改Linux服务器最大连接数来解决这个问题;
TCP概述:
服务器如何标识tcp连接?
在tcp应用中,server事先在某个固定端口监听,client主动发起连接,经过三路握手后建立tcp连接。
在确定最大连接数之前,先来看看系统如何标识一个tcp连接。系统用一个4四元组来唯一标识一个TCP连接:{local ip, local port,remote ip,remote port}。
(1) client最大tcp连接数
client每次发起tcp连接请求时,除非绑定端口,通常会让系统选取一个空闲的本地端口(local port),该端口是独占的,不能和其他tcp连接共享。
tcp端口的数据类型是unsigned short,因此本地端口个数最大只有65536,端口0有特殊含义,不能使用,这样可用端口最多只有65535,所以在全部作为client端的情况下,最大tcp连接数为65535,这些连接可以连到不同的server ip。
(2) server最大tcp连接数
server通常固定在某个本地端口上监听,等待client的连接请求。不考虑地址重用(unix的SO_REUSEADDR选项)的情况下,即使server端有多个ip,本地监听端口也是独占的,
因此server端tcp连接4元组中只有remote ip(也就是client ip)和remote port(客户端port)是可变的,因此最大tcp连接为客户端ip数×客户端port数,对IPV4,不考虑ip地址分类等因素,
最大tcp连接数约为2的32次方(ip数)×2的16次方(port数),也就是server端单机最大tcp连接数约为2的48次方。
而tcp连接受到文件句柄和端口限制,这直接限制tcp的连接数量,一般一个端口(即一个进程)的最高连接为2的16次方65536。
优化方法:
(1) 修改打开文件限制:
vim /etc/security/limits.conf
root soft nofile 65536
root hard nofile 65536
其中root指定了要修改哪个用户的打开文件数限制。
可用*号表示修改所有用户的限制;soft或hard指定要修改软限制还是硬限制;
102400则指定了想要修改的新的限制值,即最大打开文件数(请注意软限制值要小于或等于硬限制)
修改/etc/pam.d/login:
//追加代码
session required /lib/security/pam_limits.so
这是告诉Linux在用户完成系统登录后,应该调用pam_limits.so模块来设置系统对该用户可使用的各种资源数量的最大限制(包括用户可打开的最大文件数限制)。
而pam_limits.so模块就会从/etc/security/limits.conf文件中读取配置来设置这些限制值。
此设置需要重启服务器才生效,如果要不重启服务器立马生效则执行 :
# ulimit -HSn 102400
这只是在当前终端有效,退出之后,open files 又变为默认值;
(2) 系统对同时打开文件数的硬限制:
查看Linux系统对同时打开文件数的硬限制:
# sysctl -a|grep file-max
fs.file-max = 65535
这表明这台Linux系统最多允许同时打开(即包含所有用户打开文件数总和)65535个文件,是Linux系统级硬限制,所有用户级的打开文件数限制都不会超过这个数值。
通常这个系统级硬限制是Linux系统在启动时根据系统硬件资源状况计算出来的最佳的最大同时打开文件数限制。
修改file-max限制:
vim /etc/sysctl.conf
fs.file-max = 1000000
立即生效:
# sysctl -p
(3) 修改网络端口限制:
查看Linux系统最大追踪TCP连接数量:
# sysctl -a | grep ipv4.ip_conntrack_max
net.ipv4.ip_conntrack_max = 20000
这表明系统将对最大跟踪的TCP连接数限制默认为20000。
查看Linux系统端口范围:
# sysctl -a | grep ipv4.ip_local_port_range
net.ipv4.ip_local_port_range = 1024 30000
注意:
每个TCP客户端连接都要占用一个唯一的本地端口号(此端口号在系统的本地端口号范围限制中),如果现有的TCP客户端连接已将所有的本地端口号占满。将不能创建新的TCP连接。
# vi /etc/sysctl.conf
// 追加
net.ipv4.ip_local_port_range = 1024 65535
net.ipv4.ip_conntrack_max = 20000
(4) 修改linux下TCP最大连接数限制:
# vi /etc/sysctl.conf
// 追加
#该参数设置系统的TIME_WAIT的数量,如果超过默认值则会被立即清除
net.ipv4.tcp_max_tw_buckets = 20000
#定义了系统中每一个端口最大的监听队列的长度,这是个全局的参数
net.core.somaxconn = 65535
#对于还未获得对方确认的连接请求,可保存在队列中的最大数目
net.ipv4.tcp_max_syn_backlog = 262144
#在每个网络接口接收数据包的速率比内核处理这些包的速率快时,允许送到队列的数据包的最大数目
net.core.netdev_max_backlog = 30000
#能够更快地回收TIME-WAIT套接字。此选项会导致处于NAT网络的客户端超时,建议为0
net.ipv4.tcp_tw_recycle = 0
#系统所有进程一共可以打开的文件数量
fs.file-max = 6815744
#防火墙跟踪表的大小。注意:如果防火墙没开则会提示error: "net.netfilter.nf_conntrack_max" is an unknown key,忽略即可
net.netfilter.nf_conntrack_max = 2621440
运行 sysctl -p即可生效。
常用查看命令:
查看当前有多少个TCP连接到当前服务器命令: netstat -antp |grep -i est |wc -l 查看全局文件句柄数限制(系统支持的最大值): cat /proc/sys/fs/file-max 查看每个进程文件句柄数限制: ulimit -n Linux下查看tcp连接数及状态命令: netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'