1. Open File Descriptors
Linux在系统调用,大量的系统调用都依赖于文件描述符,而文件描述符可分配给进程的最大大小由资源限制来定义。
因此,如果文件描述符大小不够,或有不正常网络连接(Socket也算)、文件IO没有关闭并释放出文件描述符。也可以说是文件句柄(File Operator),会导致出现Too many open files的错误。
该错误很常见,因此OP几乎都有做优化。
使用如下命令可以查看系统相关的配置:
ulimit -u 查看open files设置
ulimit -a 查看所有配置
ulimit -u 65535 临时修改open files为65535
ulimit -n 65536 用户可以同时打开的最大文件数(max open files)
lsof -p pid ID 查看某进程当前打开的文件资源
针对所有用户及session有效的长期修改方法为:
$ sudo vim /etc/security/limits.conf
# allow all users to open 100000 files
# alternatively, replace * with an explicit username
* soft nofile 100000 #限制单个进程最大文件句柄数
* hard nofile 100000
同时需要修改/etc/sysctl.conf,设置整个系统最大文件句柄数,运行sysctl -p生效
# /etc/sysctl.conf
# Increase system file descriptor limit
fs.file-max = 100000
2TCP time wait间隔指定的时间长度,一个socket在等待FIN数据包从发送者发送时强行关闭。如果TCP没有进入CLOSED状态,主动关闭在发送最后一个ack后,就会进入TIME_WAIT。
这在Cache软件里最为常见,但其它Server也存在。
net.ipv4.tcp_fin_timeout = 30 保持FIN-WAIT-2状态时间。
net.ipv4.tcp_keepalive_time = 1200
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_tw_reuse = 1 开启重用。允许将TIME-WAIT sockets重新用于新的TCP连接,默认0,表示关闭
net.ipv4.tcp_tw_recycle = 1 开启TCP连接中TIME-WAIT sockets的快速回收,默认为0,表示关闭。
net.ipv4.ip_local_port_range = 1024 65000
# 表示用于向外连接的端口范围。
# 缺省情况下很小:32768到61000,改为18000到65535。
net.ipv4.tcp_max_syn_backlog = 8192 表示SYN队列的长度,默认1024,可以容纳更多等待连接的网络连接数。
net.ipv4.tcp_max_tw_buckets = 5000
# 表示系统同时保持TIME_WAIT套接字最大数量.
# 如果超出TIME_WAIT套接字将立刻被清除并打印警告信息。默认为180000,改为5000。
理解服务器tcp状态
10
SYN_SEND 请求服务端建立连接。
SYN_RECEIVED 服务器接收到了来自客户端的SYN。
ESTABLISHED 客户端接收到了服务端的SYN,会话建立完成。
LISTEN 服务器端开始接收连接。
FIN_WAIT_1 指示活动结束。
TIMED_WAIT 客户端在活动结束后将进入此状态。
CLOSE_WAIT 表示被动关闭。服务器只是从客户端收到第一个翼片。
FIN_WAIT_2 客户端从服务器收到其第一个 FIN 的确认。
LAST_ACK 发送自己的FIN后进入此状态。
CLOSED 服务器从客户端收到 ACK,连接已关闭。
附赵岩和我whoisd上面总结的
可以通过系统的sysctl.conf配置文件进行优化
1、减少处于FIN-WAIT-2连接状态的时间,使系统可以处理更多的连接。
net.ipv4.tcp_fin_timeout = 2
如果由本端要求关闭,这个参数决定了它保持在FIN-WAIT-2状态的时间。
对端可以出错并永远不关闭连接,甚至意外当机,缺省值是60秒。
内核的通常值是180秒,可以按这个设置,但要记住的是,即使你的机器是一个轻载的WEB服务器,也有因为大量的死套接字而内存溢出的风险,FIN-WAIT-2的危险性比FIN-WAIT-1要小,因为它最多只能吃掉1.5K内存,但是它们的生存期长些。
2、以下两参数可解决生产场景中大量连接的Web(cache)服务器中TIME_WAIT过多问题。
net.ipv4.tcp_tw_reuse = 1
表示开启重用。允许将TIME-WAIT sockets重新用于新的 TCP 连接,默认为 0 表示关闭。
3、打开TIME-WAIT重用及回收功能。
net.ipv4.tcp_tw_recycle = 1
表示开启TCP连接中TIME-WAIT sockets的快速收回功能,默认为 0 ,表示关闭。
4、当keepalive起用的时候,TCP发送keepalive消息的频度,缺省是2小时,改为20分钟。
net.ipv4.tcp_keepalive_time = 600
5、允许系统打开的端口范围
net.ipv4.ip_local_port_range = 4000 65000
表示用于向外连接的端口范围。缺省情况下很小:32768到61000,改为4000到65000。
6、提高系统支持的最大SYN半连接数(默认1024)
net.ipv4.tcp_max_syn_backlog = 16384
表示SYN队列的长度,默认为1024,加大队列长度为16384,可以容纳最多等待连接的网络连接数。
7、系统同时保持TIME_WAIT的最大数量
net.ipv4.tcp_max_tw_buckets = 360000
表示系统同时保持TIME_WAIT的最大数量,如果超过这个数字,TIME_WAIT将立刻被清除并打印警告信息。默认为180000,改为 5000。
对于Apache、Nginx等服务器,上几行的参数可以很好地减少TIME_WAIT数量,但是对于Squid,效果却不大。此项参数可以控制TIME_WAIT的最大数量,避免Squid服务器被大量的TIME_WAIT拖死。
8、路由缓存刷新频率,当一个路由失败后多长时间跳到另一个路由,默认是300。
net.ipv4.route.gc_timeout = 100
9、在内核放弃建立连接之前发送SYN包的数量。
net.ipv4.tcp_syn_retries = 1
10、减少系统SYN连接重试次数(默认是5)
net.ipv4.tcp_synack_retries = 1
为了打开对端的连接,内核需要发送一个SYN并附带一个回应前面一个SYN的ACK。
也就是所谓三次握手中的第二次握手。这个设置决定了内核放弃连接之前发送SYN+ACK包的数量。
11、设置系统对最大跟踪的TCP连接数的限制
net.ipv4.ip_conntrack_max = 25000000
一个完整的sysctl.conf文件
# /etc/sysctl.conf
# Increase system file descriptor limit
fs.file-max = 100000
# Discourage Linux from swapping idle processes to disk (default = 60)
vm.swappiness = 10
# Increase ephermeral IP ports
net.ipv4.ip_local_port_range = 10000 65000
# Increase Linux autotuning TCP buffer limits
# Set max to 16MB for 1GE and 32M (33554432) or 54M (56623104) for 10GE
# Don‘t set tcp_mem itself! Let the kernel scale it based on RAM.
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.core.rmem_default = 16777216
net.core.wmem_default = 16777216
net.core.optmem_max = 40960
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216
# Make room for more TIME_WAIT sockets due to more clients,
# and allow them to be reused if we run out of sockets
# Also increase the max packet backlog
net.core.netdev_max_backlog = 50000
net.ipv4.tcp_max_syn_backlog = 30000
net.ipv4.tcp_max_tw_buckets = 2000000
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_fin_timeout = 10
# Disable TCP slow start on idle connections
net.ipv4.tcp_slow_start_after_idle = 0
# If your servers talk UDP, also up these limits
net.ipv4.udp_rmem_min = 8192
net.ipv4.udp_wmem_min = 8192
# Disable source routing and redirects
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.all.accept_source_route = 0
# Log packets with impossible addresses for security
net.ipv4.conf.all.log_martians = 1
原文:http://wangsheng219.blog.51cto.com/2147741/1409657