0%

tcp调优参数

统计tcp各种状态的个数

netstat -an |awk ‘/^tcp/ {++state[$6]} END {for (key in state) print key,”\t”,state[key]}’

对于一个新建连接,内核要发送多少个SYN连接请求才决定放弃。默认值:6,对应于180秒左右时间,对于大负载而物理通信良好的网络而言,这个值偏高,可修改为2.这个值仅仅是针对新建对外的连接

net.ipv4.tcp_syn_retries = 2

TCP提供可靠连接的途径是通过接受方确认发送方的数据实现的,数据和确认都可能丢失,这就需要及时发现数据或者确认丢失而进行重传。重传最重要的是要确定超时间隔和重传频率。

该变量设置放弃回应一个tcp连接请求前,需要进行多少次重试。默认值:3,相当于3秒~8分钟

net.ipv4.tcp_retries1=2

缺省值是15,相当于13~30分钟,在丢弃已建立通讯的TCP连接之前﹐需要进行多少次重试,低值可以更早的检测到与远程主机失效的连接,因此服务器可以更快的释放该连接。

net.ipv4.tcp_retries2=5

对于远端的连接请求SYN,内核会发送SYN+ACK数据报,以确认收到上一个 SYN连接请求包。这是所谓的三次握手( threeway handshake)机制的第二个步骤。这里内核决定放弃连接之前所送出的SYN+ACK数目。

net.ipv4.tcp_synack_retries=3

丢弃无进程的TCP连接之前﹐要进行多少次重试。默认值为8,相当于 50秒 - 16分钟,如果您的计算机是加载的WEB服务器,则应考虑降低此值,这样的套接字可能会消耗大量资源。

tcp_orphan_retries=3

当连接关闭的时候,TCP默认缓存了很多连接指标在 route cache 中,以至于在不久的将来,连接建立的时候,可以用这些值来设置初始化条件。通常,这提升了整体的性能,但是,有时候会引起性能下降, 如果设置的话,TCP 在关闭的时候不缓存这些指标。
3.2版本之前的未打补丁的内核tcp_no_metrics_save = 0 的sysctl设置会更致命。此设置将保存数据在所有连接上,并试图用它来优化网络。不幸的是,这实际上使性能更差,因为TCP会将一个丢包的例外情况下采取的策略适用于这个客户端中几分钟的窗口内的每一个新连接。换句话说,在某些情况下,一个人从手机浏览您的网站如果一些随机数据包丢失,能够降低你的服务器的性能,尽管他。如果你希望你的访问者从移动,有损连接来了,你不能升级或修补的内核,我建议设置tcp_no_metrics_save = 1 ,Linux的3.2 的PRR能降低影响TCP性能的有损连接的数量。

net.ipv4.tcp_no_metrics_save=1

每个网络接口接收数据包的速率比内核处理这些包的速率快时,允许送到队列的最大数目,一旦超过将被丢弃。

net.core.netdev_max_backlog=262144

指定为已知的第三方应用程序保留的端口。这些端口不会被自动端口分配使用。

net.ipv4.ip_local_reserved_ports = 8000-10000

在TCP keepalive打开的情况下,最后一次数据交换到TCP发送第一个keepalive探测包的间隔,即允许的持续空闲时长,或者说每次正常发送心跳的周期,默认值为7200s。

net.ipv4.tcp_keepalive_time = 300

在tcp_keepalive_time之后,没有接收到对方确认,继续发送保活探测包的发送频率,默认值为75s。
发送频率tcp_keepalive_intvl乘以发送次数tcp_keepalive_probes,就得到了从开始探测到放弃探测确定连接断开的时间

net.ipv4.tcp_keepalive_intvl = 30

在tcp_keepalive_time之后,没有接收到对方确认,继续发送保活探测包次数,默认值为9(次)

net.ipv4.tcp_keepalive_probes = 6

若设置,服务器在客户端连接空闲的时候,每300秒发送一次保活探测包到客户端,若没有及时收到客户端的TCP Keepalive ACK确认,将继续等待30秒*6=180秒。总之可以在300s+180s=480秒时间内可检测到连接失效与否。

支持超过 64KB 的窗口的TCP窗口,使用窗口扩大选项可以使得发送端得到更大的通告窗口,这样就可以在ACK到来前发送更多的数据,减少了等待的时间,提高了数据传输效率。

net.ipv4.tcp_window_scaling=1

表示socket监听(listen)的backlog上限。什么是backlog呢?backlog就是socket的监听队列,当一个请求(request)尚未被处理或建立时,他会进入backlog。而socket server可以一次性处理backlog中的所有请求,处理后的请求不再位于监听队列中。当server处理请求较慢,以至于监听队列被填满后,新来的请求会被拒绝。限制了接收新 TCP 连接侦听队列的大小。对于一个经常处理新连接的高负载web服务环境来说,默认的 128 太小了,而nginx定义的NGX_LISTEN_BACKLOG默认为511,大多数环境这个值建议增加到 1024 或者更多。大的侦听队列对防止拒绝服务 DoS 攻击也会有所帮助。

net.core.somaxconn=65536

表示系统同时保持TIME_WAIT socket的最大数量,如果超过这个数字,TIME_WAIT套接字将立刻被清除并打印警告信息。之所以要设定这个限制﹐纯粹为了抵御那些简单的 DoS攻击﹐千万不要人为的降低这个限制﹐不过﹐如果网络条件需要比默认值更多﹐则可以提高它(或许还要增加内存)。

net.ipv4.tcp_max_tw_buckets=32768

表示系统所能处理不属于任何进程的
socket数量,当我们需要快速建立大量连接时,就需要关注下这个值了。当不属于任何进程的socket的数量大于这个值时,dmesg就会看
到”too many of orphaned sockets”。

net.ipv4.tcp_max_orphans=65536

linux中查看socket状态:

cat /proc/net/sockstat
sockets: used 137 TCP: inuse 49 orphan 0 tw 3272 alloc 52 mem 46 UDP: inuse 1 mem 0 RAW: inuse 0 FRAG: inuse 0 memory 0

下面几行的参数可以很好的减少TIME_WAIT数量

在 tcp 建立连接的 3 路握手过程中,当服务端收到最初的 SYN 请求时,会检查应用程序的 syn_backlog 队列是否已满。若已满,通常行为是丢弃此 SYN 包。若未满,会再检查应用程序的backlog队列是否已满。若已满并且系统根据历史记录判断该应用程序不会较快消耗连接时,则丢弃此 SYN 包。如果启用 tcp_syncookies 则在检查到 syn_backlog 队列已满时,不丢弃该 SYN 包,而改用 syncookie 技术进行 3 路握手。
警告:使用 syncookie 进行握手时,因为该技术挪用了 tcp_options 字段空间,会强制关闭 tcp 高级流控技术而退化成原始 tcp 模式。此模式会导致 封包 丢失时 对端 要等待 MSL 时间来发现丢包事件并重试,以及关闭连接时 TIME_WAIT 状态保持 2MSL 时间。该技术应该仅用于保护 syn_flood 攻击。如果在正常服务器环境中服务器负载较重导致 syn_backlog 和 backlog 队列满时,应优化 服务端应用程序 的 负载能力,加大应用程序 backlog 值。不过,所幸该参数是自动值,仅在 syn_backlog 队列满时才会触发 (在队列恢复可用时此行为关闭)。
启用 syncookie 虽然也可以解决超高并发时的 can’t connect 问题,但会导致 TIME_WAIT 状态 fallback 为保持 2MSL 时间,高峰期时会导致客户端无可复用连接而无法连接服务器 (tcp 连接复用是基于 <src_ip, src_port, dst_ip, dst_port> 四元组值必须不相同,就访问同一个目标服务器而言,<src_ip, dst_ip, dst_port> 三元组值不变,所以此时可用的连接数限制为仅 src_port 所允许数目,这里处于 TIME_WAIT 状态的相同 src_port 连接不可复用。Linux 系统甚至更严格,只使用了 <src_ip, src_port, dst_ip> 三元组…)。故不建议依赖 syncookie。

net.ipv4.tcp_syncookies=1

net.ipv4.tcp_tw_reuse=1
表示开启重用。允许将TIME-WAIT sockets重新用于新的TCP连接,默认为0,表示关闭;
启用net.ipv4.tcp_tw_reuse后,如果新的时间戳,比以前存储的时间戳更大,那么linux将会从TIME-WAIT状态的存活连接中,选取一个,重新分配给新的连接出去的TCP连接。

net.ipv4.tcp_tw_recycle=0
表示开启TCP连接中TIME-WAIT sockets的快速回收,默认为0,表示关闭。
TCP有一种行为,可以缓存每个连接最新的时间戳,后续请求中如果时间戳小于缓存的时间戳,即视为无效,相应的数据包会被丢弃。
特别注意的是:当client与server之间有如NAT这类网络转换设备时,开启tcp_tw_recycle选项可能会导致server端drop(直接发送RST)来自client的SYN包。
当请求到达LVS后,它修改地址数据后便转发给后端服务器,但不会修改时间戳数据,对于后端服务器来说,请求的源地址就是LVS的地址,加上端口会复用,所以从后端服务器的角度看,原本不同客户端的请求经过LVS的转发,就可能会被认为是同一个连接,加之不同客户端的时间可能不一致,所以就会出现时间戳错乱的现象,于是后面的数据包就被丢弃了,具体的表现通常是是客户端明明发送的SYN,但服务端就是不响应ACK,如果服务器身处NAT环境,安全起见,通常要禁止tcp_tw_recycle,至于TIME_WAIT连接过多的问题,可以通过激活tcp_tw_reuse来缓解

net.ipv4.ip_local_port_range = 32768 60999 net.ipv4.ip_local_port_range = 1024 65535
当系统中某一时刻同时存在太多的TCP客户端连接时,由于每个TCP客户端连接都要占用一个唯一的本地端口号(此端口号在系统的本地端口号范围限制中),如果现有的TCP客户端连接已将所有的本地端口号占满,则此时就无法为新的TCP客户端连接分配一个本地端口号了,因此系统会在这种情况下在connect()调用中返回失败,并将错误提示消息设为“Can’t assignrequested address”。最好是这些数字有不同的奇偶性。(一个偶数和一个奇数值)默认值分别为32768和60999。

net.ipv4.tcp_max_syn_backlog=262144
表示SYN队列的长度,默认为1024,加大队列长度为8192,可以容纳更多等待连接的网络连接数。syn_backlog 队列实际上是个 hash 表,并且 hash 表大小为 2 的次方。所以实际 syn_backlog 的队列长度要 略大于 应用程序设置的 backlog 值 —— 取对应 2 的次方值。

net.ipv4.tcp_fin_timeout=30
这个参数是用来设置保持在FIN_WAIT_2状态的时间。tcp四次挥手,正常的处理流程就是在FIN_WAIT_2情况下接收到FIN进入到TIME_WAIT的情况,tcp_fin_timeout参数对处于TIME_WAIT状态的时间没有任何影响。但是如果这个参数设的比较小,会缩短从FIN_WAIT_2到TIME_WAIT的时间,从而使连接更早地进入TIME_WAIT状态。状态开始的早,等待相同的时间,结束的也早,客观上也加速了TIME_WAIT状态套接字的清理速度。

编辑完成后,请执行以下命令使变动立即生效:
/sbin/sysctl -p
/sbin/sysctl -w net.ipv4.route.flush=1—