前言
查看本文之前,可以先查看关于本博客TCP 状态文章,连接TCP 各个状态就会更好理解下文的性能调优的有意。
为什么要性能调优?
大部分的linux发行版是为了完全兼容市场中大部分计算机而设计的。这是一个相当混杂的硬件集合(硬盘,显卡,网卡,等等)。所以Red Hat, Suse,Mandriva和其他的一些发行版厂商选择了一些保守的设置来确保安装成功。
简单地说:你的发行版运行的很好,但是它可以运行地更好!
比如,可能有一个具体一些特殊特性的高级硬盘,而这些特性在标准配置的情况下可能就没被启用。
example for 磁盘子系统的调优
对于Linux的Ext3/4来说,几乎在所有情况下都有所帮助的一个参数是关闭文件系统访问时间,在/etc/fstab下看看你的文件系统 有没有noatime参数.atime 是最近访问文件的时间,每当访问文件时,底层文件系统必须记录这个时间戳。因为系统管理员很少使用 atime,禁用它可以减少磁盘访问时间。禁用这个特性的方法是,在 /etc/fstab 的第四列中添加 noatime 选项。
noatime
内核参数调整说明
所有的内核当前状态都会显示再/proc/...目录下,可以用过cat 去查看,但是如果想要调整有三种方式:
临时(重启后失效)
echo "1" > /proc/sys/net/ipv4/conf/all/send_redirects #注意proc虚拟文件i系统,只能echo 不可vim 编辑
sysctl -w net.ipv4.ipfrag_low_thresh=262144
永久
vi /etc/sysctl.conf
net.ipv4.conf.default.accept_source_route = 0
sysctl -p
sysctl 命令使用
-w 临时改变某个指定参数的值
sysctl -w net.ipv4.ipfrag_low_thresh=262144
-a 显示所有的系统参数
sysctl -a
-p 从指定的文件加载系统参数,默认从/etc/sysctl.conf 文件中加载,使得配置文件中配置立即生效
sysctl -p /etc/sysctl.conf
proc 中内核配置路径与sysctl -a 显示对应关系
/proc/sys/net/ipv4/ipfrag_low_thresh --> net.ipv4.ipfrag_low_thresh #多了一个proc/sys ,后面对应一致
网络调优(性能)
tcp连接保持管理:
net.ipv4.tcp_keepalive_time = 7200 # 如果在该参数指定时间内某条连接处于空闲状态,则内核向远程主机发起探测
net.ipv4.tcp_keepalive_intvl = 75 # 多久探测一次
net.ipv4.tcp_keepalive_probes = 9 # 连续探测次数
tips:
内核发送保活探测的最大9次,如果探测次数大于这个数,则断定远程主机不可达,则关闭该连接并释放本地资源,一个连接7200s空闲后,内核会每隔75秒去重试,若连续9次则放弃。这样就导致一个连接经过2h11min的时间才能被丢弃,降低该值能够尽量减小失效连接所占用的资源,而被新的连接所使用。
net.core.netdev_max_backlog=3000 #表示在每个网络接口接收数据包的速率比内核处理这些包的速率快时,允许送到队列的数据包的最大数目。
net.ipv4.tcp_max_syn_backlog = 1024 #控制每个端口的tcp syn的队列长度,来自客户端的连接请求需要排队,直至服务器接受,如果连接请求数大于该值,则连接请求会被丢弃,客户端无法连接服 务器,一般服务器要提高此值
net.ipv4.tcp_synack_retries = 5 #控制内核向某个socket的ack,syn段(三次握手的第二次握手)重新发送响应的次数,降低此值可以尽早检测到来自远程主机的连接失败尝试
net.ipv4.tcp_retries2 = 15 #控制内核向已建立连接的远程主机重新发送数据的次数,降低此值,可以尽早的检测连接失效
net.ipv4.tcp_synCOOKIEs = 1 #TCP SYN包并返回TCP SYN+ACK包时,不分配一个专门的数据区,而是根据这个SYN包计算出一个COOKIE值。在收到TCP ACK包时,TCP服务器在根据那个COOKIE值检查这个TCP ACK包的合法性。如果合法,再分配专门的数据区进行处理未来的TCP连接。
网络调优(安全+性能)
net.ipv6.conf.all.disable_ipv6 = 1 #关闭ipv6 默认开启
net.ipv6.conf.default.disable_ipv6 = 1
net.ipv4.tcp_tw_recycle = 1 #启用timewait 快速回收
net.ipv4.tcp_synCOOKIEs = 1 #开SYN洪水攻击保护
处理无源路由的包,防止黑客对服务器IP地址的攻击
net.ipv4.conf.eth0.accept_source_route=0
net.ipv4.conf.lo.accept_source_route=0
net.ipv4.conf.default.accept_source_route=0
net.ipv4.conf.all.accept_source_route=0
服务器忽略来自被列入网关的服务器的重定向。因重定向可以被用来进行攻击,所以我们只接受有可靠来源的重定向
net.ipv4.conf.eth0.secure_redirects=1
net.ipv4.conf.lo.secure_redirects=1
net.ipv4.conf.default.secure_redirects=1
net.ipv4.conf.all.secure_redirects=1
可以配置接受或拒绝任何ICMP重定向。ICMP重定向是器传输信息的机制。比如,当网关接收到来自所接网络主机的Internet数据报时,网关可以发送重定向信息到一台主机。网关检查路由表获得下一个网关的地址,第二个网关将数据报路由到目标网络。关闭这些重定向得命令如下
net.ipv4.conf.eth0.accept_redirects=0
net.ipv4.conf.lo.accept_redirects=0
net.ipv4.conf.default.accept_redirects=0
net.ipv4.conf.all.accept_redirects=0
如果这个服务器不是一台路由器,那么它不会发送重定向,所以可以关闭该功能:
net.ipv4.conf.eth0.send_redirects=0
net.ipv4.conf.lo.send_redirects=0
net.ipv4.conf.default.send_redirects=0
net.ipv4.conf.all.send_redirects=0
net.ipv4.icmp_echo_ignore_broadcasts=1 #开启icmp广播忽略,拒绝接受广播风暴或者smurf 攻击attacks:
net.ipv4.icmp_echo_ignore_all=1 #忽略所有icmp包或者pings
net.ipv4.icmp_ignore_bogus_error_responses=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.tcp_fin_timeout = 60 #对于本端断开的socket连接,TCP保持在FIN_WAIT_2状态的时间
tips:
对于本端断开的socket连接,TCP保持在FIN_WAIT_2状态的时间。对方可能会断开连接或一直不结束连接或不可预料的进程死亡。默认值为 60 秒。过去在2.2版本的内核中是 180 秒。您可以设置该值﹐但需要注意﹐如果您的机器为负载很重的web服务器﹐您可能要冒内存被大量无效数据报填满的风险﹐FIN-WAIT-2 sockets 的危险性低于 FIN-WAIT-1 ﹐因为它们最多只吃 1.5K 的内存﹐但是它们存在时间更长。另外参考 tcp_max_orphans。
CLOSE_WAIT状态的生成原因
如果服务器程序APACHE处于CLOSE_WAIT状态的话,说明套接字是被动关闭的!
假设CLIENT端主动断掉当前连接,那么双方关闭这个TCP连接共需要四个packet:
Client —> FIN —> Server
Client <--- ACK <--- Server
这时候Client端处于FIN_WAIT_2状态&#xff1b;而Server 程序处于CLOSE_WAIT状态。
Client <--- FIN <--- Server
这时Server 发送FIN给Client&#xff0c;Server 就置为LAST_ACK状态。
Client ---> ACK —> Server
Client回应了ACK&#xff0c;那么Server 的套接字才会真正置为CLOSED状态。
Server 程序处于CLOSE_WAIT状态&#xff0c;而不是LAST_ACK状态&#xff0c;说明还没有发FIN给Client&#xff0c;那么可能是在关闭连接之前还有许多数据要发送或者其他事要做&#xff0c;导致没有发这个FIN packet。
通常来说&#xff0c;一个CLOSE_WAIT会维持至少2个小时的时间。如果有个流氓特地写了个程序&#xff0c;给你造成一堆的CLOSE_WAIT&#xff0c;消耗资源&#xff0c;那么通常是等不到释放那一刻&#xff0c;系统就已经解决崩溃了。
改变这个值的前要经过认真的监测,避免因为死套接字造成内存溢出。
net.ipv4.core.wmem_max&#61;8388608 #对于所有的队列&#xff08;即系统&#xff09;&#xff0c;设置最大系统发送缓存(wmem) 和接收缓存(rmem)到8MB
net.ipv4.core.rmem_max&#61;8388608
使用如下命令调整tcp发送和接收缓存。该命令设定了三个值&#xff1a;最小值、初始值和最大值
net.ipv4.tcp_rmem&#61;"4096 87380 8388608" #调整tcp读取缓存
net.ipv4.tcp.wmem&#61;"4096 87380 8388608" #调整tcp写入缓存
net.ipv4.tcp_max_syn_backlog&#61;4096
tips:
第三个值必须小于或等于wmem_max和rmem_max。
当服务器负载繁重或者是有很多客户端都是超长延时的连接故障&#xff0c;可能会导致half-open连接数量的增加。这对于Web服务器很来讲很平常&#xff0c;尤其有很多拨号客户时。这些half-open连接保存在 backlog&#xff08;积压&#xff09; connections 队列中。
将这个值最少设置为4096 (缺省为1024)。 即便是服务器不接收这类连接&#xff0c;设置这个值还能防止受到denial-of-service (syn-flood)的攻击
设置ipfrag参数&#xff0c;尤其是NFS和Samba服务器
net.ipv4.ipfrag_low_thresh&#61;262144
net.ipv4.ipfrag_high_thresh&#61;393216
tips:
这里&#xff0c;我们可以设置用于重新组合IP碎片的最大、最小内存。当ipfrag_high_thresh值被指派&#xff0c;碎片会被丢弃直到达到ipfrag_low_thres值。
当TCP数据包传输发生错误时&#xff0c;开始碎片整理。有效的数据包保留在内存&#xff0c;同时损坏的数据包被转发。例如&#xff0c;设置可用内存范围从256 MB到384 MB
转载自&#xff1a;https://blog.csdn.net/universe_hao/article/details/52220159