TCP、HTTP服务器内核参数优化

1,896 阅读15分钟

〇、引言


本文旨在介绍 TCP/HTTP x64 linux 服务器在部署的过程中,为避免一些罕见问题,或者需要针对性地提高服务器并发性能时,需要注意的大部分内核参数调优。读者可以直接跳转到文末,复制相应的内核参数调优范本直接应用,也可继续阅读。如有发现缺失的或不当的参数调优,烦请告知。

当前参数查询:sysctl -a
参数配置文件:/etc/sysctl.conf
参数更新指令:sudo /sbin/sysctl -p
参数技术文档:link
ps: 若有个别参数配置不合法,执行更新指令时会有提示,但并不影响其他参数的更新

本文的内核参数调优仅在 IPv4 协议堆栈下进行测试,暂不支持 IPv6 协议。由于三大运营商联合阿里云,计划在 2025 年前助推中国互联网真正实现 “IPv6 Only”,即国内 IPv4 预计在 2025 年被大规模禁用,因此本文时效为 2020~2025 年。

一、参数类型


  1. 内核子系统配置(通常前缀为: kernel. )
  2. 网络子系统配置(通常前缀为: net. )
  3. 虚拟内存子系统配置(通常前缀为: vm. )
  4. MDADM 子系统配置(通常前缀为: dev. )

二、网络性能提高


优化一:业务负载很高时,需要调高服务器端口最大监听队列的长度

内核参数配置:
net.ipv4.tcp_max_syn_backlog = 65535
net.core.somaxconn = 65535
必要性说明:

在客户端服务器的 TCP 3 次握手过程中,对于服务器而言,一个完整建立的连接会经历 2 种 TCP 状态:SYN_RCVD 和 ESTABLISHED。为此服务器的 TCP 协议维护了两个队列:

  1. 一个存放 SYN_RCVD 的队列(半连接队列)
  2. 一个存放 ESTABLISHED 的队列(全连接队列)

假如一个服务器需要处理大量网络连接,且并发性较高,那么这两个队列的长度就显得十分重要。我们很容易验证,即使是一台硬件配置很高的服务器,在这两个队列长度配置过小的情况下,由于队列很容易排满,将不可避免地频繁出现丢包和连接 Reset 的现象。原因在于,当排队的连接数大于设定的队列长度时,后续进来的连接都会被丢弃,包括半连接和全连接。频繁的连接丢弃将加重 CPU 和 网卡的负荷。

参数说明:
  • somaxconn 该全局参数设置 socket listen() 系统调用的 accept 队列即全连接队列长度,默认值为 4096,目前考虑网络并发性能,调高到 65535
  • tcp_max_syn_backlog 该全局参数决定了系统中处于 SYN_RECV 状态的 TCP 连接数量,默认值为 1024,在服务器经常过载的情况下,可以尝试调高该参数,目前调高到 65535

优化二:大量连接建立断开,TIME_WAIT 状态的 TCP 连接将非常多,需要调整 TIME_WAIT 状态的限制数量,避免 “kernel: TCP: time wait bucket table overflow” 报错

内核参数配置
net.ipv4.tcp_max_tw_buckets = 65535
必要性说明:

该参数设置系统可容纳的处于 TIME_WAIT 的 TCP 连接的数量,如果超过参数设定值,内核将立即回收超出设定值部分的 TCP 连接,我们可以通过调高系统可容纳的 TIME_WAIT 数量来尽量避免这一情况,因为内核频繁强制回收大量 TCP 连接将占用不必要的 CPU 资源,导致服务延时走高。

优化三:在内核开启并编译 CONFIG_SYN_COOKIES 的情况下,启用 SYN_COOKIES 防止一个 socket 在收到过多恶意连接请求时,因过载而影响正常连接请求的及时响应,即防止 SYN 洪水攻击。

内核参数配置
net.ipv4.tcp_syncookies = 1
必要性说明:

当参数被设置为 1 ,且 SYN_RCVD 队列满了之后,内核会对 SYN 包的回复做一定的修改,即在响应的 SYN+ACK 包中,将 ACK 返回的序列号改为由源 IP+Port、目的 IP+Port 及时间五个参数共同计算出的一个加密值,服务器在响应 SYN+ACK 包后立即释放连接,即不维护本次的半连接。此时,正常的连接将返回加密后的 ACK 序列号的确认,服务器收到后直接建立起全连接,避免了半连接中间状态的资源消耗。而由于 SYN+ACK 包中 ACK 的确认序列号并不是之前客户端计算的值,恶意攻击者借助 IP 欺骗发起的 SYN 洪水攻击无法响应或误判,就起到了防止 SYN 洪水攻击的效果。

注意,假如 /var/log/message 日志文件的 SYN flood 警告是由于正常连接过多导致的,那单独启用 SYN_COOKIES 是消除不了这种报错的,而应通过调整 tcp_max_syn_backlog、tcp_synack_retries 或 tcp_abort_on_overflow 参数来解决。

优化四:减少 SYN+ACK 重传次数,更好应对 SYN 洪水攻击

内核参数配置:
net.ipv4.tcp_synack_retries = 2
必要性说明:

该参数用于调整,处于 SYN_RECV 状态时重传 SYN+ACK 包的次数,默认为 5 次,此处调低到 2 次。

优化五:设置 TCP 栈内存的使用规则(示例机器内存 4G)

内核参数配置:
# TCP 内存使用低于 0.5G 时不做干扰
# 使用 1.5G 内存后启动 TCP 内存压力模式,直到内存使用 低于 0.5G 时关闭内存压力模式
# 内存使用上限为 3G
# 参数数值单位为页,大部分系统内存页默认是 4K,可通过命令获取当前内存页大小:$ getconf PAGE_SIZE
# 反向计算方法:131072 * 4K = 524288 K = 512 M = 0.5 G
# 正向计算方法: 0.5 G = 512 M = 512 * 1024 K / 4K = 131072
net.ipv4.tcp_mem = 131072 393216 786432  

# TCP Socket 接收缓冲区分配的最小字节数为 1K
# 接收缓冲区在内存负载不高时的默认值 4K
# 接收缓冲区的最大字节数 6M
net.ipv4.tcp_rmem = 1024 4096 6291456

# TCP Socket 发送缓冲区分配的最小字节数为 1K
# 发送缓冲区在内存负载不高时的默认值 4K
# 发送缓冲区的最大字节数 4M
net.ipv4.tcp_wmem = 1024 4096 4194304

# 其他协议如 UDP Socket 默认的数据发送缓冲区大小,单位字节,约 852.7K
net.core.wmem_default = 873200

# 各类 Socket 的最大数据发送缓冲区大小,单位字节,4M
net.core.wmem_max = 4194304

# 其他协议如 UDP Socket 默认的数据接收缓冲区大小,单位字节,约 852.7K
net.core.rmem_default = 873200

# 各类 Socket 的最大数据接收缓冲区大小,单位字节,6M
net.core.rmem_max = 6291456
参数说明:
  • net.ipv4.tcp_mem 规定 TCP 栈对内存使用各个水位的反应,每个值的单位都是内存页(大小通常是 4K)。 第一个值是低水位,当内存使用页数低于该数值时不做干扰。 第二个值是压力水位,即 TCP 内存压力模式的触发线,触发压力模式后,当内存使用低于低水位时压力模式将自动解除。 第三个值是高水位,即 TCP 内存使用的上限。当 TCP 内存使用达到上限时将丢弃无法处理的 TCP 包。

  • net.ipv4.tcp_rmem 规定单个 Socket 使用的接收缓冲区内存。 第一个值是为 Socket 接收缓冲区分配的最少字节数,默认是 4K。 第二个值是默认分配的字节数(覆盖 rmem_default 的值),接收缓冲区在内存负载不高时的默认值。默认 16K。 第三个值是接收缓冲区的最大字节数(不覆盖 rmem_max 的值)。默认在 87380B ~ 6MB 之间,取决于机器内存大小。

  • net.ipv4.tcp_wmem 规定单个 Socket 使用的发送缓冲区内存。 第一个值是为 Socket 发送缓冲区分配的最少字节数,默认是 4K。 第二个值是默认分配的字节数(覆盖 wmem_default 的值),发送缓冲区在内存负载不高时的默认值。默认 16K。 第三个值是发送缓冲区的最大字节数(不覆盖 wmem_max 的值)。默认在 64K ~ 4MB 之间,取决于机器内存大小。

  • net.core.rmem_default 各类 Socket 的默认数据接收缓冲区大小(字节)

  • net.core.rmem_max 各类 Socket 的最大数据接收缓冲区大小(字节)

  • net.core.wmem_default 各类 Socket 的默认数据发送缓冲区大小(字节)

  • net.core.wmem_max 各类 Socket 的最大数据发送缓冲区大小(字节)

优化六:增大业务高峰期网络数据包过载时的排队队列

内核参数配置:
net.core.netdev_max_backlog = 16384
必要性说明:

当业务处于高峰期,此时较大概率会出现内核处理速度慢于网卡接收速度的情况,这时尚未被处理的包就会被保存在网卡设备的接收队列上,而 netdev_max_backlog 参数则用来调整这个队列的长度,表示在每个网卡接收数据包的速率比内核处理的速率快时,允许送到队列的数据包的最大数目。适当调高该参数,能有效缓解高峰期的网络堵塞。

优化七:缩短 sliently dead tcp connection 在服务器的存活时间

内核参数配置:
net.ipv4.tcp_keepalive_time = 1800
net.ipv4.tcp_keepalive_intvl = 30
net.ipv4.tcp_keepalive_probes = 3
必要性说明:

在网络高并发场景下,无效 TCP 连接长时间存在将导致不必要的内存占用,致使内存使用比预计偏高。因此需要通过参数调优降低无效 TCP 连接的容忍时间,提高内存的使用效益。

参数说明:
  • net.ipv4.tcp_keepalive_time TCP发送 keepalive 探测消息的间隔秒数,用于确认TCP连接是否有效。 默认是 2 小时,目前改为 30 分钟。

  • net.ipv4.tcp_keepalive_intvl 探测消息未获得响应时,重发该消息的间隔秒数。 默认是 75 秒,目前改为 30 秒。

  • net.ipv4.tcp_keepalive_probes 在认定TCP连接失效之前,最多发送多少个keepalive探测消息。 默认是 9 次,目前改为 3 次。

优化八:扩大可用端口的范围

内核参数配置:
net.ipv4.ip_local_port_range = 1024 65535
必要性说明:

默认情况下,TCP/UDP 协议允许使用的本地端口号范围为 32768~61000,这限制了服务器进程的端口使用,导致不必要的可用端口浪费,因此可以扩大 TCP/UDP 的端口使用范围,目前可用的最大范围即 1024 ~ 65535。

优化九:降低服务器主动断开的 TCP 连接保持在 FIN_WAIT_2 状态的时间,避免 FIN_WAIT_2 状态的 TCP 连接过多

内核参数配置:
net.ipv4.tcp_fin_timeout = 20
必要性说明:

在 HTTP 接口服务过程中,服务器由于某些原因会主动关闭连接,如 KEEPALIVE 超时的情况,此时主动关闭的连接就会进入 FIN_WAIT2 状态。 而 FIN_WAIT2 状态不计算超时,假如客户端一直不关闭连接或发生不可预料的进程死亡,FIN_WAIT2 状态的连接将保持到系统重启,越来越多的 FIN_WAIT2 状态会致使内核 Crash。 因此,建议调小 net.ipv4.tcp_fin_timeout 参数的值,以便加快系统关闭处于 FIN_WAIT2 状态的 TCP 连接。 默认值为 60 s,目前调整为 20 s。

优化十:提高路由缓存刷新频率,避免 “route hash chain too long” 问题

内核参数配置:
net.ipv4.route.gc_timeout = 100
参数说明:

路由缓存刷新频率,单位为秒,规定当一个路由失败后,多长时间跳到另一个路由,默认是 300。

优化十一:提高系统中可以同时打开的文件数目

内核参数优化:
fs.file-max=10485760

优化十二:开启 SysRq 键排除和诊断系统故障

内核参数优化:
kernel.sysrq=1
必要性说明:

SysRq 可以在系统挂起,大多数服务已无法响应的情况下,还能通过按键组合来完成一系列预先定义的系统操作。通过它,不但可以在保证磁盘数据安全的情况下重启一台挂起的服务器,避免数据丢失和重启后长时间的文件系统检查,还可以收集包括系统内存使用,CPU 任务处理,进程运行状态等系统运行信息,甚至还可能在无需重启的情况下挽回一台已经停止响应的服务器。 详细请见:link

优化十三:降低内核新建连接失败后的重试次数

内核参数配置:
net.ipv4.tcp_syn_retries = 2
必要性说明:

新建连接时内核要发送 5 个 SYN 连接请求才决定放弃,这对大负载而物理通信良好的网络而言,明显偏高,因此这里改成 2 次。这个值针对的是对外连接,进来的连接由 tcp_retries1 决定。

优化十四:减少回收 TCP 连接前的最大重传次数

内核参数配置:
net.ipv4.tcp_retries2 = 11
必要性说明:

最大重传次数设置为 11 次后,即约 204.8 秒(RFC1122规定,必须大于100秒)收不到 ACK报文,最后一次重传失败,内核回收该 TCP 连接。初始值为 15,重传超时时间为 3276.8 秒。

优化十五:允许 OS 对大部分申请内存的请求都回复同意,以便跑更多更大的程序。因为申请内存后,并不会马上使用内存。

内核参数配置:
vm.overcommit_memory = 1
必要性说明:

vm.overcommit_memory 表示内核的内存分配策略,有三种取值: 0:表示内核将检查是否有足够的可用内存供应用进程使用;如果有足够的可用内存,内存申请允许;否则,内存申请失败,并把错误返回给应用进程。 1:表示内核允许分配所有的物理内存,而不管当前的内存状态如何。 2:表示内核禁止分配超过所有物理内存和交换空间总和的内存 对大部分内存申请都回复同意,否则在低内存情况下,可能会出现磁盘保存丢失的情况。同时也能更快速有效地完成内核的内存分配。

优化十六:TCP 包头添加时间戳,以一种比重发超时更精确的方法启用对 RTT 的计算,实现更好的性能

内核参数配置:
net.ipv4.tcp_tw_recycle = 0
net.ipv4.tcp_timestamps = 1

三、进程安全保障


配置文件位置:

/etc/security/limits.conf

配置参数:
*         hard    nofile      610000
*         soft    nofile      610000
root      hard    nofile      610000
root      soft    nofile      610000
配置效果:

通过限制单进程最大文件数来控制单进程接收到的连接数,以实现连接超负载时的新连接自动拒绝,同时又不影响其他进程。 如以上示例,限制单进程最大文件数为 610000,则理想情况下单进程最多能建立 61 万 TCP 连接。

生效方式:

退出当前用户后重新登录即可 查看指令:$ ulimit -n

四、罕见问题规避


问题一:部署在同一内网网段下的ECS之间无法通信?

内核参数配置:
net.ipv4.conf.default.arp_announce = 2
net.ipv4.conf.lo.arp_announce = 2
net.ipv4.conf.all.arp_announce = 2
参数说明:
  • net.ipv4.conf.default.arp_announce 主机或路由器在 ARP 广播时,广播数据包的源 IP 地址并不是固定的,可以从多个本地虚拟网卡(下文简称网卡)的 IP 地址中选择。这一源 IP 地址的选择通过 arp_announce 参数的不同取值来限制,arp_announce 参数的各个限制等级如下: 0:任意本地网卡上配置的 IP 地址都可使用,一般会用默认网卡的源 IP 地址; 1:尽量避免使用与目标主机 IP 地址不在同一子网的源 IP 地址,如果目标主机 IP 地址的子网不存在,对源 IP 地址的选择限制将按等级 2 的来;(这一模式在目标主机要求 ARP 广播的源 IP 地址与接收网卡的 IP 地址必须在同一网段时有用) 2:根据目标主机 IP 地址来选择最合适的源 IP 地址,若目标主机 IP 地址与所有本地源 IP 地址都不在同一网段,选用本地第一个发送网卡的源 IP 地址。 net.ipv4.conf.default.arp_announce 用于控制对默认网卡 ARP 广播数据包源 IP 地址的选择限制等级。

  • net.ipv4.conf.lo.arp_announce 控制对 lo 网卡 ARP 广播数据包源 IP 地址的选择限制等级。

  • net.ipv4.conf.all.arp_announce 控制对所有网卡 ARP 广播数据包源 IP 地址的选择限制等级。

  • net.ipv4.conf.{all/interface_name}.arp_announce 各个网卡的 arp_announce 参数配置字段名 arp_announce = max( net.ipv4.conf.all.arp_announce, net.ipv4.conf.interface_name.arp_announce )

概念说明:
  • ARP:地址解析协议( Address Resolution Protocol ) 在以太网协议中规定,同一局域网中的一台主机要和另一台主机进行直接通信,必须要知道目标主机的 MAC 地址。而在 TCP/IP 协议中,网络层和传输层只关心目标主机的 IP 地址。这就导致在以太网中使用 IP 协议时,数据链路层的以太网协议接到上层 IP 协议提供的数据中,只包含目的主机的 IP 地址。于是需要一种方法,根据目的主机的 IP 地址,获得其 MAC 地址。这就是 ARP 协议要做的事情。所谓地址解析就是主机在发送帧前将目标 IP 地址转换成目标 MAC 地址的过程。 另外,当发送主机和目的主机不在同一个局域网中时,即便知道对方的 MAC 地址,两者也不能直接通信,必须经过路由转发才可以。所以此时,发送主机通过 ARP 协议获得的将不是目的主机的真实 MAC 地址,而是一台可以通往局域网外的路由器的 MAC 地址。

  • ARP 广播:ARP Request 每台安装有 TCP/IP 协议的主机或路由器里都有一个 ARP 缓存表,当在 ARP 缓存表没有找到相应的 IP 地址,主机A就会在网络上发送一个广播,向同一网段内的所有主机发出询问,相应 IP 地址的主机B通过单播的方式响应主机A,这样,主机A就知道主机B的MAC地址,可以向主机B发送信息,同时还更新 ARP 缓存表。

具体配置说明:
# 默认网卡 ARP 广播时,根据目标主机 IP 地址来选择最合适的源 IP 地址
net.ipv4.conf.default.arp_announce = 2
# lo 网卡 ARP 广播时,根据目标主机 IP 地址来选择最合适的源 IP 地址
net.ipv4.conf.lo.arp_announce = 2
# 所有网卡 ARP 广播时,根据目标主机 IP 地址来选择最合适的源 IP 地址
net.ipv4.conf.all.arp_announce = 2
关联参数说明:
  • net.ipv4.conf.{all/interface_name}.arp_announce net.ipv4.conf.all.arp_ignore net.ipv4.conf.default.arp_ignore ... arp_ignore 参数用于设置对 ARP 广播的响应模式,各个模式说明如下: 0:响应所有目的 IP 地址与任一本地 IP 地址匹配的ARP广播 1:只响应目的 IP 地址与当前接收网卡的 IP 地址匹配的ARP广播 2:只响应目的 IP 地址与当前接收网卡的 IP 地址匹配,且源 IP 地址与目的 IP 地址在同一子网网段的 ARP 广播; 3:不响应作用域为仅当前主机内可用的 IP 地址( scope host ),如 127.0.0.1;只回应作用域为子网范围( link address, 如子网广播 IP )或公网范围( global address )的 IP 地址; 4-7:保留值 8:不响应所有的 ARP 广播
其他说明

使用 LVS + DR 负载均衡模式时,要求 arp_ignore = 1, arp_announce = 2

问题二:关联到TCP负载均衡服务的ECS实例无法正常访问?

内核参数配置:
net.ipv4.conf.default.rp_filter =  0  
net.ipv4.conf.all.rp_filter =  0  
net.ipv4.conf.lo.rp_filter =  0
参数说明:
  • net.ipv4.conf.default.rp_filter rp_filter 参数控制对数据包源地址的校验,各个模式如下: 0:不开启源地址校验; 1:开启严格的反向路径校验。对每个进来的数据包,校验其反向路径是否最佳路径。如果反向路径不是最佳路径,则直接丢弃该数据包。最佳实践模式,可预防 DDos 攻击的 IP 欺骗; 2:开启宽松的反向路径校验。对每个进来的数据包,校验反向路径是否能通(通过任意网卡),如果反向路径不同,则直接丢弃该数据包。在使用复杂路由或非对称路由时推荐使用。 net.ipv4.conf.default.rp_filter 控制默认网卡对数据包源地址的校验
  • net.ipv4.conf.all.rp_filter 控制所有网卡对数据包源地址的校验
  • net.ipv4.conf.lo.rp_filter 控制 lo 网卡对数据包源地址的校验
概念说明:
  • DDos 攻击 当黑客使用网络上两个或以上被攻陷的电脑作为“僵尸”向特定的目标发动“拒绝服务”式攻击时,称为分布式拒绝服务攻击(distributed denial-of-service attack,简称 DDoS 攻击)。

  • IP 欺骗(IP Spoofing) 指带有假的源 IP 地址的 IP 数据报,目的是冒充另一个计算机身份。

具体配置说明:
# 默认网卡不开启源地址校验
net.ipv4.conf.default.rp_filter =  0
# 所有网卡不开启源地址校验
net.ipv4.conf.all.rp_filter =  0
# lo 网卡不开启源地址校验
net.ipv4.conf.lo.rp_filter =  0

问题三:因网络硬件设备 IPv6 协议支持不完善、软件网络模块实现的 IPv6 标准不一致(旧 RFC2460 和 新 RFC8200)、或软件网络模块不支持 IPv6 导致的网络连接失败或连接频繁断开问题?

内核参数配置:
net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1
net.ipv6.conf.lo.disable_ipv6 = 1
具体配置说明:
# 禁止所有网卡的 IPv6 协议操作
net.ipv6.conf.all.disable_ipv6 = 1
# 禁止默认网卡的 IPv6 协议操作
net.ipv6.conf.default.disable_ipv6 = 1
# 禁止 lo 网卡的 IPv6 协议操作
net.ipv6.conf.lo.disable_ipv6 = 1
其他说明:

2018-2019全球IPv6支持度白皮书

问题四:线上生产环境机器的内存使用会出现周期性的高峰,而这一峰值在远没到达机器物理内存时,却开始使用 swap?(使用 swap 将占用大量的 CPU 资源,外在表现为较大的服务延迟)

内核参数配置:
vm.swappiness = 0
参数说明:
  • vm.swappiness 取值范围:0-100 参数意义:用于控制系统 swap 的使用程度,通过调低 swappiness 内核参数,降低系统对 swap 分区的使用依赖,从而提高系统性能。默认值 swappiness = 60,即当内存使用达到 100-60=40% 时,开始使用 swap 分区。swappiness=0 则表示最大限度使用物理内存。
概念说明:
  • kswapd0 在虚拟内存管理中负责换页的进程,OS 每过一段时间唤醒进程来检查内存使用情况。 存在 2 个阀值,pages_hige 和 pages_low,如空闲内存页数量达到 pages_hige,则进程睡眠,如空闲内存页数量低于 pages_low,kswapd0 进程将扫描内存并每次释放 32 个空闲内存页,直到空闲内存页的数量到达 pages_high。 通过设置大页内存,可以阻止 kswapd0 进程过度活跃地消耗 CPU。
  • 大页内存 Linux 基于 hugetlb 特殊文件系统的大页面支持为应用程序的灵活性和性能优化提供了方便。 使用大页内存能减少系统管理和访问页的时间;内核中的 swap 守护进程也不会管理大页面占用的这部分空间。合理设置大页面能减少内存操作的负担,减少访问页表造成性能瓶颈的可能性,从而提升系统性能。 一般情况下,配置的大页面主要供特定的应用程序或服务使用,如大规模的科学计算应用,以避免大页面的使用浪费。
具体参数说明
# 最大限度使用物理内存
vm.swappiness = 0
关联参数:
  • kernel.shmall 表示系统任意时刻可以分配的所有共享内存段的总和的最大值(以页为单位),最小值为 ceil( kernel.shmmax / PAGE_SIZE ) 通过控制 SHMALL 参数值低于可用内存,可避免 CPU 将还用不到的程序或数据换出到磁盘。 配置例子(4G RAM):kernel.shmall = 1048576 (4 * 1024 * 1024 * 1024 / 4096,PAGE_SIZE = 4096)
其他说明:

少量使用 swap 空间是不会影响性能的,一般只有在内存出现瓶颈,导致频繁、大量的 swap 分区使用时,才会引起 kswapd0 进程耗用大量 CPU 资源,从而严重降低系统性能。

次选配置方案:
# 在物理内存使用率达到 90% 时,开始 swap 分区使用
vm.swappiness = 10
# 控制系统可分配的所有共享内存段总和的最大值
# 该参数值需自行计算,val = (Total Memory / PAGE_SIZE)
# PAGE_SIZE 获取命令: $ getconf PAGE_SIZE
kernel.shmall = 1048576

问题五:系统日志的 Default arp cache timeout 报错频繁

内核参数配置:
net.ipv4.neigh.default.gc_stale_time = 120
参数说明:
  • gc_stale_time 检查过期 ARP 缓存记录的周期,当一个记录过期时,在重新向该 IP 对应的 Mac 地址发送数据前,ARP 协议将重新解析一次该 IP,即再次 ARP 广播。 默认值为 60 s,在分布式服务器集群场景下,常常会有需要每分钟通讯一次的主机群,此时将 gc_stale_time 调高到 120s 能降低集群下的 ARP 广播频率。
具体参数说明:
# 检查过期 ARP 缓存记录周期延长到 120s
net.ipv4.neigh.default.gc_stale_time = 120
其他说明:

在自部署 DHCP 服务器时,常见 Neighbour table overflow 的系统日志报错,这是由于服务器收到的 ARP 广播压力过大导致,以下给出客户端主机数量在 500 左右的 DHCP 内核参数配置示例:

# Force gc to clean-up quickly
net.ipv4.neigh.default.gc_interval = 3600
# Setup reachable time
net.ipv4.neigh.default.base_reachable_time = 86400
# Set ARP cache entry timeout
net.ipv4.neigh.default.gc_stale_time = 86400
# Setup DNS threshold for arp
nnet.ipv4.neigh.default.gc_thresh1 = 4096
net.ipv4.neigh.default.gc_thresh2 = 8192
net.ipv4.neigh.default.gc_thresh3 = 8192

查看当前 Neighbour table 的命令:$ ip -s neighbor show

五、HTTP、TCP 服务器内核参数调优范本


/etc/sysctl.conf

net.ipv4.conf.default.arp_announce = 2
net.ipv4.conf.lo.arp_announce = 2
net.ipv4.conf.all.arp_announce = 2

net.ipv4.conf.default.rp_filter =  0  
net.ipv4.conf.all.rp_filter =  0  
net.ipv4.conf.lo.rp_filter =  0

net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1
net.ipv6.conf.lo.disable_ipv6 = 1

vm.swappiness = 0

net.ipv4.neigh.default.gc_stale_time = 120

net.ipv4.tcp_max_syn_backlog = 65535
net.core.somaxconn = 65535
net.ipv4.tcp_max_tw_buckets = 65535
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_synack_retries = 2

net.core.netdev_max_backlog = 16384
net.ipv4.tcp_keepalive_time = 1800
net.ipv4.tcp_keepalive_intvl = 30
net.ipv4.tcp_keepalive_probes = 3
net.ipv4.ip_local_port_range = 1024 65535
net.ipv4.tcp_fin_timeout = 20
net.ipv4.route.gc_timeout = 100
fs.file-max=10485760
kernel.sysrq=1
net.ipv4.tcp_syn_retries = 2
net.ipv4.tcp_retries2 = 11
vm.overcommit_memory = 1
net.ipv4.tcp_tw_recycle = 0
net.ipv4.tcp_timestamps = 1

 # 以下配置需要自行根据机器内存衡量,示例机器内存为 4G

# TCP 内存使用低于 0.5G 时不做干扰
# 使用 1.5G 内存后启动 TCP 内存压力模式,直到内存使用 低于 0.5G 时关闭内存压力模式
# 内存使用上限为 3G
# 参数数值单位为页,大部分系统内存页默认是 4K,可通过命令获取当前内存页大小:$ getconf PAGE_SIZE
# 反向计算方法:131072 * 4K = 524288 K = 512 M = 0.5 G
# 正向计算方法: 0.5 G = 512 M = 512 * 1024 K / 4K = 131072
net.ipv4.tcp_mem = 131072 393216 786432  

# TCP Socket 接收缓冲区分配的最小字节数为 1K
# 接收缓冲区在内存负载不高时的默认值 4K
# 接收缓冲区的最大字节数 6M
net.ipv4.tcp_rmem = 1024 4096 6291456

# TCP Socket 发送缓冲区分配的最小字节数为 1K
# 发送缓冲区在内存负载不高时的默认值 4K
# 发送缓冲区的最大字节数 4M
net.ipv4.tcp_wmem = 1024 4096 4194304

# 其他协议如 UDP Socket 默认的数据发送缓冲区大小,单位字节,约 852.7K
net.core.wmem_default = 873200

# 各类 Socket 的最大数据发送缓冲区大小,单位字节,4M
net.core.wmem_max = 4194304

# 其他协议如 UDP Socket 默认的数据接收缓冲区大小,单位字节,约 852.7K
net.core.rmem_default = 873200

# 各类 Socket 的最大数据接收缓冲区大小,单位字节,6M
net.core.rmem_max = 6291456

/etc/security/limits.conf

*         hard    nofile      610000
*         soft    nofile      610000
root      hard    nofile      610000
root      soft    nofile      610000
* hard core unlimited
* soft core unlimited