因为在做爬虫分布式系统的过程中,涉及到了一些linux
系统优化方面的知识,所以来总结一下,我们会对linux
的不同模块做相关的基本优化,这篇文章主要讲述的是关于tcp协议栈
的参数优化。
1.机器环境
Linux EOS01 2.6.32-358.el6.x86_64 #1 SMP Fri Feb 22 00:31:26 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux
CentOS release 6.4 (Final)
2.具体实施
2.1 由于每台机器的文件描述符都是处于默认的1024
的标准值,对于高并发的系统来说,很容易达到瓶颈,因此我们需要重定文件描述符数量,可以采用ansible
对各个服务器批量设置。
vi /etc/security/limits.conf
* soft nofile 65535
* hard nofile 65535
* soft nproc 65535
* hard nproc 65535
2.2 关于我们对于系统tcp
协议栈的参数设置
vi /etc/sysctl.conf
net.ipv4.tcp_fin_timeout=10
net.ipv4.tcp_syncookies=1
#开启重用。允许将TIME-WAIT sockets 重新用于新的TCP 连接
net.ipv4.tcp_tw_reuse=1
#启用timewait 快速回收
net.ipv4.tcp_tw_recycle=1
net.ipv4.ip_local_port_range=1024 65000
net.ipv4.tcp_max_syn_backlog=8192
net.ipv4.tcp_max_tw_buckets=5000
net.ipv4.tcp_timestamps = 0
#每300秒 探测一次tcp连接是否空闲,一共探测2次,每次间隔15秒
net.ipv4.tcp_keepalive_intvl = 15
net.ipv4.tcp_keepalive_probes = 2
net.ipv4.tcp_keepalive_time = 300
然后执行 /sbin/sysctl -p 让参数生效
具体的参数含义可以参考如下:
1. fs.file-max
最大可以打开的文件描述符数量,注意是整个系统。
在服务器中,我们知道每创建一个连接,系统就会打开一个文件描述符,所以,文件描述符打开的最大数量也决定了我们的最大连接数
select在高并发情况下被取代的原因也是文件描述符打开的最大值,虽然它可以修改但一般不建议这么做,详情可见unp select部分。
2.net.ipv4.tcp_max_syn_backlog
Tcp syn队列的最大长度,在进行系统调用connect时会发生Tcp的三次握手,server内核会为Tcp维护两个队列,Syn队列和Accept队列,Syn队列是指存放完成第一次握手的连接,Accept队列是存放完成整个Tcp三次握手的连接,修改net.ipv4.tcp_max_syn_backlog使之增大可以接受更多的网络连接。
注意此参数过大可能遭遇到Syn flood攻击,即对方发送多个Syn报文端填充满Syn队列,使server无法继续接受其他连接
可参考此文http://tech.uc.cn/?p=1790
我们看下 man 手册上是如何说的:
The behavior of the backlog argument on TCP sockets changed with Linux 2.2. Now it specifies the queue length for com‐ pletely 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. See tcp(7) for more information. If the backlog argument is greater than the value in /proc/sys/net/core/somaxconn, then it is silently truncated to that value; the default value in this file is 128. In kernels before 2.4.25, this limit was a hard coded value, SOMAXCONN, with the value 128.
自 Linux 内核 2.2 版本以后,backlog 为已完成连接队列的最大值,未完成连接队列大小以 /proc/sys/net/ipv4/tcp_max_syn_backlog 确定,但是已连接队列大小受 SOMAXCONN 限制,为 min(backlog, SOMAXCONN)
3.net.ipv4.tcp_syncookies
修改此参数可以有效的防范上面所说的syn flood攻击
原理:在Tcp服务器收到Tcp Syn包并返回Tcp Syn+ack包时,不专门分配一个数据区,而是根据这个Syn包计算出一个cookie值。在收到Tcp ack包时,Tcp服务器在根据那个cookie值检查这个Tcp ack包的合法性。如果合法,再分配专门的数据区进行处理未来的TCP连接。
默认为0,1表示开启
4.net.ipv4.tcp_keepalive_time
Tcp keepalive心跳包机制,用于检测连接是否已断开,我们可以修改默认时间来间断心跳包发送的频率。
keepalive一般是服务器对客户端进行发送查看客户端是否在线,因为服务器为客户端分配一定的资源,但是Tcp 的keepalive机制很有争议,因为它们可耗费一定的带宽。
Tcp keepalive详情见Tcp/ip详解卷1 第23章
5.net.ipv4.tcp_tw_reuse
我的上一篇文章中写到了time_wait状态,大量处于time_wait状态是很浪费资源的,它们占用server的描述符等。
修改此参数,允许重用处于time_wait的socket。
默认为0,1表示开启
6.net.ipv4.tcp_tw_recycle
也是针对time_wait状态的,该参数表示快速回收处于time_wait的socket。
默认为0,1表示开启
7.net.ipv4.tcp_fin_timeout
修改time_wait状的存在时间,默认的2MSL
注意:time_wait存在且生存时间为2MSL是有原因的,见我上一篇博客为什么会有time_wait状态的存在,所以修改它有一定的风险,还是根据具体的情况来分析。
8.net.ipv4.tcp_max_tw_buckets
所允许存在time_wait状态的最大数值,超过则立刻被清楚并且警告。
9.net.ipv4.ip_local_port_range
表示对外连接的端口范围。
10.somaxconn
前面说了Syn队列的最大长度限制,somaxconn参数决定Accept队列长度,在listen函数调用时backlog参数即决定Accept队列的长度,该参数太小也会限制最大并发连接数,因为同一时间完成3次握手的连接数量太小,server处理连接速度也就越慢。服务器端调用accept函数实际上就是从已连接Accept队列中取走完成三次握手的连接。
Accept队列和Syn队列是listen函数完成创建维护的。
/proc/sys/net/core/somaxconn修改
3. 参考资料
https://blog.csdn.net/Lixuanshengchao/article/details/81606168