Linux 常用内核网络参数与相关问题处理

  • A+
所属分类:Linux
高性能企业级服务器首台5折

本文总结了常见的 Linux 内核参数及相关问题。修改内核参数前,您需要:

  • 从实际需要出发,最好有相关数据的支撑,若您的业务没有受到影响不建议调整内核参数。
  • 了解每一个参数的具体作用,并且同类型或版本操作系统下内核参数可能有所不同。
  • 备份 ECS 实例中的重要数据。参阅文档创建快照

Linux 常用内核网络参数

参数 描述
net.core.rmem_default 默认的 TCP 数据接收窗口大小(字节)。
net.core.rmem_max 最大的 TCP 数据接收窗口(字节)。
net.core.wmem_default 默认的 TCP 数据发送窗口大小(字节)。
net.core.wmem_max 最大的 TCP 数据发送窗口(字节)。
net.core.netdev_max_backlog 在每个网络接口接收数据包的速率比内核处理这些包的速率快时,允许送到队列的数据包的最大数目。
net.core.somaxconn 定义了系统中每一个端口最大的监听队列的长度,这是个全局的参数。
net.core.optmem_max 表示每个套接字所允许的最大缓冲区的大小。
net.ipv4.tcp_mem 确定 TCP 栈应该如何反映内存使用,每个值的单位都是内存页(通常是 4KB)
第一个值是内存使用的下限;
第二个值是内存压力模式开始对缓冲区使用应用压力的上限;
第三个值是内存使用的上限。在这个层次上可以将报文丢弃,从而减少对内存的使用。对于较大的 BDP 可以增大这些值(注意:其单位是内存页而不是字节)。
net.ipv4.tcp_rmem 为自动调优定义 socket 使用的内存。
第一个值是为 socket 接收缓冲区分配的最少字节数;
第二个值是默认值(该值会被 rmem_default 覆盖),缓冲区在系统负载不重的情况下可以增长到这个值;
第三个值是接收缓冲区空间的最大字节数(该值会被 rmem_max 覆盖)。
net.ipv4.tcp_wmem 为自动调优定义 socket 使用的内存。
第一个值是为 socket 发送缓冲区分配的最少字节数;
第二个值是默认值(该值会被 wmem_default 覆盖),缓冲区在系统负载不重的情况下可以增长到这个值;
第三个值是发送缓冲区空间的最大字节数(该值会被 wmem_max 覆盖)。
net.ipv4.tcp_keepalive_time TCP 发送 keepalive 探测消息的间隔时间(秒),用于确认 TCP 连接是否有效。
net.ipv4.tcp_keepalive_intvl 探测消息未获得响应时,重发该消息的间隔时间(秒)。
net.ipv4.tcp_keepalive_probes 在认定 TCP 连接失效之前,最多发送多少个 keepalive 探测消息。
net.ipv4.tcp_sack 启用有选择的应答(1 表示启用),通过有选择地应答乱序接收到的报文来提高性能,让发送者只发送丢失的报文段,(对于广域网通信来说)这个选项应该启用,但是会增加对 CPU 的占用。
net.ipv4.tcp_fack 启用转发应答,可以进行有选择应答(SACK)从而减少拥塞情况的发生,这个选项也应该启用。
net.ipv4.tcp_timestamps TCP 时间戳(会在 TCP 包头增加 12 B),以一种比重发超时更精确的方法(参考 RFC 1323)来启用对 RTT 的计算,为实现更好的性能应该启用这个选项。
net.ipv4.tcp_window_scaling 启用 RFC 1323 定义的 window scaling,要支持超过 64KB 的 TCP 窗口,必须启用该值(1 表示启用),TCP 窗口最大至 1GB,TCP 连接双方都启用时才生效。
net.ipv4.tcp_syncookies 表示是否打开 TCP 同步标签(syncookie),内核必须打开了 CONFIG_SYN_COOKIES 项进行编译,同步标签可以防止一个套接字在有过多试图连接到达时引起过载。默认值 0 表示关闭。
net.ipv4.tcp_tw_reuse 表示是否允许将处于 TIME-WAIT 状态的 socket (TIME-WAIT 的端口)用于新的 TCP 连接。
net.ipv4.tcp_tw_recycle 能够更快地回收 TIME-WAIT 套接字。
net.ipv4.tcp_fin_timeout 对于本端断开的 socket 连接,TCP 保持在 FIN-WAIT-2 状态的时间(秒)。对方可能会断开连接或一直不结束连接或不可预料的进程死亡。
net.ipv4.ip_local_port_range 表示 TCP/UDP 协议允许使用的本地端口号。
net.ipv4.tcp_max_syn_backlog 对于还未获得对方确认的连接请求,可保存在队列中的最大数目。如果服务器经常出现过载,可以尝试增加这个数字。默认为 1024。
net.ipv4.tcp_low_latency 允许 TCP/IP 栈适应在高吞吐量情况下低延时的情况,这个选项应该禁用。
net.ipv4.tcp_westwood 启用发送者端的拥塞控制算法,它可以维护对吞吐量的评估,并试图对带宽的整体利用情况进行优化,对于 WAN 通信来说应该启用这个选项。
net.ipv4.tcp_bic 为快速长距离网络启用 Binary Increase Congestion,这样可以更好地利用以 GB 速度进行操作的链接,对于 WAN 通信应该启用这个选项。
net.ipv4.tcp_max_tw_buckets 该参数设置系统的 TIME_WAIT 的数量,如果超过默认值则会被立即清除。默认为 180000。
net.ipv4.tcp_synack_retries 指明了处于 SYN_RECV 状态时重传 SYN+ACK 包的次数。
net.ipv4.tcp_abort_on_overflow 设置改参数为 1 时,当系统在短时间内收到了大量的请求,而相关的应用程序未能处理时,就会发送 Reset 包直接终止这些链接。建议通过优化应用程序的效率来提高处理能力,而不是简单地 Reset。
默认值: 0
net.ipv4.route.max_size 内核所允许的最大路由数目。
net.ipv4.ip_forward 接口间转发报文。
net.ipv4.ip_default_ttl 报文可以经过的最大跳数。
net.netfilter.nf_conntrack_tcp_timeout_established 让 iptables 对于已建立的连接,在设置时间内若没有活动,那么则清除掉。
net.netfilter.nf_conntrack_max 哈希表项最大值。

查看和修改 Linux 实例内核参数

方法一、通过 

1
/proc/sys/

 目录

1
/proc/sys/

 目录是 Linux 内核在启动后生成的伪目录,其目录下的 

1
net

 文件夹中存放了当前系统中生效的所有内核参数、目录树结构与参数的完整名称相关,如 

1
net.ipv4.tcp_tw_recycle

,它对应的文件是 

1
/proc/sys/net/ipv4/tcp_tw_recycle

,文件的内容就是参数值。

查看内核参数:使用 

1
cat

 查看对应文件的内容,例如执行命令 

1
cat /proc/sys/net/ipv4/tcp_tw_recycle

 查看 

1
net.ipv4.tcp_tw_recycle

 的值。

修改内核参数:使用 

1
echo

 修改内核参数对应的文件,例如执行命令 

1
echo "0" > /proc/sys/net/ipv4/tcp_tw_recycle

 将 

1
net.ipv4.tcp_tw_recycle

 的值修改为 0。

注意方法一修改的参数值仅在当次运行中生效,系统重启后会回滚历史值,一般用于临时性的验证修改的效果。若需要永久性的修改,请参阅方法二

方法二、通过 

1
sysctl.conf

 文件

查看内核参数:执行命令 

1
sysctl -a

 查看当前系统中生效的所有参数,如下所示:

  1. 1
    <span class="pln">net</span><span class="pun">.</span><span class="pln">ipv4</span><span class="pun">.</span><span class="pln">tcp_app_win </span><span class="pun">=</span> <span class="lit">31</span>
  2. 1
    <span class="pln">net</span><span class="pun">.</span><span class="pln">ipv4</span><span class="pun">.</span><span class="pln">tcp_adv_win_scale </span><span class="pun">=</span> <span class="lit">2</span>
  3. 1
    <span class="pln">net</span><span class="pun">.</span><span class="pln">ipv4</span><span class="pun">.</span><span class="pln">tcp_tw_reuse </span><span class="pun">=</span> <span class="lit">0</span>
  4. 1
    <span class="pln">net</span><span class="pun">.</span><span class="pln">ipv4</span><span class="pun">.</span><span class="pln">tcp_frto </span><span class="pun">=</span> <span class="lit">2</span>
  5. 1
    <span class="pln">net</span><span class="pun">.</span><span class="pln">ipv4</span><span class="pun">.</span><span class="pln">tcp_frto_response </span><span class="pun">=</span> <span class="lit">0</span>
  6. 1
    <span class="pln">net</span><span class="pun">.</span><span class="pln">ipv4</span><span class="pun">.</span><span class="pln">tcp_low_latency </span><span class="pun">=</span> <span class="lit">0</span>
  7. 1
    <span class="pln">net</span><span class="pun">.</span><span class="pln">ipv4</span><span class="pun">.</span><span class="pln">tcp_no_metrics_save </span><span class="pun">=</span> <span class="lit">0</span>
  8. 1
    <span class="pln">net</span><span class="pun">.</span><span class="pln">ipv4</span><span class="pun">.</span><span class="pln">tcp_moderate_rcvbuf </span><span class="pun">=</span> <span class="lit">1</span>
  9. 1
    <span class="pln">net</span><span class="pun">.</span><span class="pln">ipv4</span><span class="pun">.</span><span class="pln">tcp_tso_win_divisor </span><span class="pun">=</span> <span class="lit">3</span>
  10. 1
    <span class="pln">net</span><span class="pun">.</span><span class="pln">ipv4</span><span class="pun">.</span><span class="pln">tcp_congestion_control </span><span class="pun">=</span><span class="pln"> cubic</span>
  11. 1
    <span class="pln">net</span><span class="pun">.</span><span class="pln">ipv4</span><span class="pun">.</span><span class="pln">tcp_abc </span><span class="pun">=</span> <span class="lit">0</span>
  12. 1
    <span class="pln">net</span><span class="pun">.</span><span class="pln">ipv4</span><span class="pun">.</span><span class="pln">tcp_mtu_probing </span><span class="pun">=</span> <span class="lit">0</span>
  13. 1
    <span class="pln">net</span><span class="pun">.</span><span class="pln">ipv4</span><span class="pun">.</span><span class="pln">tcp_base_mss </span><span class="pun">=</span> <span class="lit">512</span>
  14. 1
    <span class="pln">net</span><span class="pun">.</span><span class="pln">ipv4</span><span class="pun">.</span><span class="pln">tcp_workaround_signed_windows </span><span class="pun">=</span> <span class="lit">0</span>
  15. 1
    <span class="pln">net</span><span class="pun">.</span><span class="pln">ipv4</span><span class="pun">.</span><span class="pln">tcp_challenge_ack_limit </span><span class="pun">=</span> <span class="lit">1000</span>
  16. 1
    <span class="pln">net</span><span class="pun">.</span><span class="pln">ipv4</span><span class="pun">.</span><span class="pln">tcp_limit_output_bytes </span><span class="pun">=</span> <span class="lit">262144</span>
  17. 1
    <span class="pln">net</span><span class="pun">.</span><span class="pln">ipv4</span><span class="pun">.</span><span class="pln">tcp_dma_copybreak </span><span class="pun">=</span> <span class="lit">4096</span>
  18. 1
    <span class="pln">net</span><span class="pun">.</span><span class="pln">ipv4</span><span class="pun">.</span><span class="pln">tcp_slow_start_after_idle </span><span class="pun">=</span> <span class="lit">1</span>
  19. 1
    <span class="pln">net</span><span class="pun">.</span><span class="pln">ipv4</span><span class="pun">.</span><span class="pln">cipso_cache_enable </span><span class="pun">=</span> <span class="lit">1</span>
  20. 1
    <span class="pln">net</span><span class="pun">.</span><span class="pln">ipv4</span><span class="pun">.</span><span class="pln">cipso_cache_bucket_size </span><span class="pun">=</span> <span class="lit">10</span>
  21. 1
    <span class="pln">net</span><span class="pun">.</span><span class="pln">ipv4</span><span class="pun">.</span><span class="pln">cipso_rbm_optfmt </span><span class="pun">=</span> <span class="lit">0</span>
  22. 1
    <span class="pln">net</span><span class="pun">.</span><span class="pln">ipv4</span><span class="pun">.</span><span class="pln">cipso_rbm_strictvalid </span><span class="pun">=</span> <span class="lit">1</span>

修改内核参数

  1. 执行命令 
    1
    /sbin/sysctl -w kernel.domainname="example.com"

     来修改指定的参数值,如

    1
    sysctl -w net.ipv4.tcp_tw_recycle="0"
  2. 执行命令 
    1
    vi /etc/sysctl.conf

     修改 

    1
    /etc/sysctl.conf

     文件中的参数。

  3. 执行命令 
    1
    /sbin/sysctl -p

     使配置生效。

Linux 网络相关内核参数引发的常见问题及处理

问题现象 原因分析 解决方案
无法在本地网络环境通过 SSH 连接 ECS Linux 实例,或者访问该 Linux 实例上的 HTTP 业务出现异常。Telnet 测试会被 reset。 如果您的本地网络是 NAT 共享方式上网,该问题可能是由于本地 NAT 环境和目标 Linux 相关内核参数配置不匹配导致。
尝试通过修改目标 Linux 实例内核参数来解决问题:
1. 远程连接目标 Linux 实例;
2. 查看当前配置: cat /proc/sys/net/ipv4/tcp_tw_recyclecat /proc/sys/net/ipv4/tcp_timestamps 查看上述两个配置的值是不是 0,如果为 1的话,NAT 环境下的请求可能会导致上述问题。
通过如下方式将上述参数值修改为 0:
1. 执行命令 

1
vi /etc/sysctl.conf


2. 添加如下内容:

1
net.ipv4.tcp_tw_recycle=0net.ipv4.tcp_timestamps=0


3. 输入指令 

1
# sysctl -p

 使配置生效。
4. 重新 SSH 登录实例或者业务访问测试。

服务端 A 与 客户端 B 建立了 TCP 连接,之后服务端 A 主动断开了连接,但是在客户端 B 上仍然看到连接是建立的。示例见图一图二 通常是由于修改了服务端内核参数 

1
net.ipv4.tcp_fin_timeout

 默认设置所致。

1. 执行命令 

1
vi /etc/sysctl.conf

,修改配置:

1
net.ipv4.tcp_fin_timeout=30


2. 执行命令 

1
# sysctl -p

 使配置生效。

通过 netstat 或 ss 可以看到大量处于 TIME_WAIT 状态的连接。 通过 

1
netstat -n | awk ‘/^tcp/ {++y[$NF]} END {for(w in y) print w, y[w]}’

 查看 TIME_WAIT 数量。

1. 执行命令 

1
vi /etc/sysctl.conf

,修改或加入以下内容:

  1. net.ipv4.tcp_syncookies = 1
    net.ipv4.tcp_tw_reuse = 1
    net.ipv4.tcp_tw_recycle = 1
    net.ipv4.tcp_fin_timeout = 30

2. 执行命令 

1
/sbin/sysctl -p 

 使配置生效。

云服务器上出现大量 CLOSE_WAIT 状态的连接数。 根据实例上的业务量来判断 CLOSE_WAIT 数量是否超出了正常的范围。TCP 连接断开时需要进行四次挥手,TCP 连接的两端都可以发起关闭连接的请求,若对端发起了关闭连接,但本地没有进行后续的关闭连接操作,那么该链接就会处于 CLOSE_WAIT 状态。虽然该链接已经处于半开状态,但是已经无法和对端通信,需要及时的释放该链接。建议从业务层面及时判断某个连接是否已经被对端关闭,即在程序逻辑中对连接及时进行关闭检查。 通过命令 

1
netstat -an|grep CLOSE_WAIT|wc -l

 查看当前实例上处于 CLOSE_WAIT 状态的连接数。
Java 语言:
1. 通过 

1
read

 方法来判断 I/O 。当 read 方法返回 

1
-1

 时则表示已经到达末尾。
2. 通过 

1
close

 方法关闭该链接。
C 语言:
1. 检查 read 的返回值,若是 0 则可以关闭该连接,若小于 0 则查看一下 errno,若不是 AGAIN 则同样可以关闭连接。

ECS Linux FIN_WAIT2 状态的 TCP 链接过多。 HTTP 服务中,SERVER 由于某种原因关闭连接,如 KEEPALIVE 的超时。这样,作为主动关闭的 SERVER 一方就会进入 FIN_WAIT2 状态。但 TCP/IP 协议栈中,FIN_WAIT2 状态是没有超时的(不像 TIME_WAIT 状态),如果 Client 不关闭,FIN_WAIT_2 状态将保持到系统重启,越来越多的 FIN_WAIT_2 状态会致使内核 Crash。 1. 执行命令 

1
vi /etc/sysctl.conf

,修改或加入以下内容:

  1. net.ipv4.tcp_syncookies = 1
    net.ipv4.tcp_fin_timeout = 30
    net.ipv4.tcp_max_syn_backlog = 8192
    net.ipv4.tcp_max_tw_buckets = 5000

2. 执行命令 

1
# sysctl -p

 使配置生效。

查询服务器 /var/log/message 日志,发现全部是类似如下 kernel: TCP: time wait bucket table overflowt的报错信息,报错提示 TCP time wait 溢出,见图三 TCP 连接使用很高,容易超出限制。见图四 1. 执行命令 

1
netstat -anp |grep tcp |wc -l

统计 TCP 连接数。
2. 对比 /etc/sysctl.conf 配置文件的 

1
net.ipv4.tcp_max_tw_buckets

 最大值,看是否有超出情况。
3. 执行命令 

1
vi /etc/sysctl.conf

,查询 

1
net.ipv4.tcp_max_tw_buckets

 参数。如果确认连接使用很高,容易超出限制。
4. 调高参数 

1
net.ipv4.tcp_max_tw_buckets

,扩大限制。
5. 执行命令 

1
# sysctl -p

 使配置生效。

ECS Linux 实例出现间歇性丢包的情况,通过 tracert, mtr 等手段排查,外部网络未见异常。同时,如下图所示,在系统日志中重复出现大量kernel nf_conntrack: table full, dropping packet.错误信息。见图五 ip_conntrack 是 Linux 系统内 NAT 的一个跟踪连接条目的模块。ip_conntrack 模块会使用一个哈希表记录 TCP 通讯协议的 established connection 记录,当哈希表满了的时候,会导致 nf_conntrack: table full, dropping packet 错误。需要通过修改内核参数来调整 ip_conntrack 限制。 Centos 5.x 系统
1. 使用管理终端登录实例。
2. 执行命令 

1
# vi /etc/sysctl.conf

 编辑系统内核配置。
3. 修改哈希表项最大值参数:

1
net.ipv4.netfilter.ip_conntrack_max = 655350


4. 修改超时时间参数:

1
net.ipv4.netfilter.ip_conntrack_tcp_timeout_established = 1200

,默认情况下 timeout 是5天(432000秒)。
5. 执行命令 

1
# sysctl -p

 使配置生效。Centos 6.x 及以上系统:
1. 使用管理终端登录实例。
2. 执行命令 

1
# vi /etc/sysctl.conf

 编辑系统内核配置。
3. 修改哈希表项最大值参数:

1
net.netfilter.nf_conntrack_max = 655350


4. 修改超时时间参数:

1
net.netfilter.nf_conntrack_tcp_timeout_established = 1200

,默认情况下 timeout 是5天(432000秒)。
5. 执行命令 

1
# sysctl -p

 使配置生效。

客户端做了 NAT 后无法访问 ECS、RDS,包括通过 SNAT VPC 访问外网的 ECS 。无法访问连接其他 ECS 或 RDS 等云产品,抓包检测发现远端对客户端发送的 SYN 包没有响应。 若远端服务器同时开启 net.ipv4.tcp_tw_recycle 和 net.ipv4.tcp_timestamps,即参数取值为 1 时,服务器会检查每一个报文的时间戳(Timestamp),若 Timestamp 不是递增的关系,则不做处理。做了 NAT 后,服务器看到来自不同的客户端的 IP 相似,但 NAT 前每一台客户端的时间可能会有偏差,在服务器上就会看到 Timestamp 不是递增的情况。 - 远端服务器为 ECS:
修改参数 net.ipv4.tcp_tw_recycle 为 0。
- 远端服务器为 RDS 等 PaaS 服务:
RDS 无法直接修改内核参数,需要在客户端上修改参数 net.ipv4.tcp_tw_recycle 和 net.ipv4.tcp_timestamps 为 0。

参考链接

  1. Linux man-pages
  2. kernel/git/torvalds/linux.git_proc
  3. kernel/git/torvalds/linux.git_proc_net_tcp
  4. kernel/git/torvalds/linux.git_ip-sysctl
  5. kernel/git/torvalds/linux.git_netfilter-sysctl
  6. kernel/git/torvalds/linux.git_nf_conntrack-sysctl

图一: 客户端 B TCP 连接

clientb

图二: 客户端 A TCP 连接

clienta

图三: 报错提示 TCP time wait 溢出

kernel

图四: 查询 net.ipv4.tcp_max_tw_buckets 参数

parameter

图五: ECS Linux 实例间歇性丢包

Linuxnat

 

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: