Linux系统:内核参数调优

时间:2024-03-08 08:48:03

目录

1、/proc目录

2、sysctl命令

3.1 控制源路由验证

3.2  控制内核的系统请求调试功能

3.3  控制核心转储是否将PID附加到核心文件名

3.4 控制TCP同步cookie的使用

3.5  在网桥上禁用netfilter

3.6  控制消息队列的默认最大大小 

3.7  调试TCP内核参数

3.8  调试套接字缓冲区

3.9 调试与TCP连接管理相关

3.10 TCP连接重用 

3.11  TCP连接保活(Keepalive)和本地端口范围

3.12 swap分区 

4、优化内核参数(nginx)


1、/proc目录

  • /proc目录是一个特殊的虚拟文件系统,它不包含常规的文件,而是包含当前运行中的内核和进程信息
  • 这个目录允许用户和程序访问系统内核的很多信息,比如CPU、内存、进程等。在/proc目录下,每个数字命名的子目录代表一个正在运行的进程,其中包含了该进程的相关信息,比如进程ID、状态、内存使用情况等
  • 此外,/proc还提供了一些用于配置内核参数的接口,允许用户动态地修改内核的某些行为

2、sysctl命令

sysctl命令用于在运行时动态地修改内核参数,而无需重新启动系统。这个命令允许用户检索、设置和修改内核的运行时参数。通过sysctl,可以查看当前系统的各种内核参数设置,并且可以进行修改

相关配置文件 说明
/etc/sysctl.conf 默认配置文件
/run/sysctl.d/*.conf 这个目录包含了在系统引导过程中自动生成的临时文件,通常用于覆盖其他位置的配置
/etc/sysctl.d/*.conf 在这个目录下,用户可以创建自定义的配置文件,每个文件包含一个或多个对内核参数的设置。这些设置会在系统启动时被加载
/usr/local/lib/sysctl.d/*.conf 该目录用于存放本地安装的软件所提供的sysctl配置文件
/usr/lib/sysctl.d/*.conf 这个目录包含由软件包提供的sysctl配置文件
/lib/sysctl.d/*.conf 这个目录包含由操作系统提供的sysctl配置文件,通常由发行版的维护者管理

sysctl命令用法:

(1)查看参数

sysctl -a   #列出所有的内核参数及其当前值

[root@localhost ~]#sysctl -a | grep ip_forward

 (2)查看特定参数

sysctl kernel.parameter_name    #查看特定参数的值
[root@localhost ~]#sysctl net.ipv4.ip_forward

 (3)临时修改参数值

sysctl -w parameter_name=new_value     #临时修改参数的值,但重启后会恢复为默认值

(4)永久修改参数值:

通过修改/etc/sysctl.conf文件来实现永久修改参数的值,然后使用sysctl -p命令使更改生效

(5)刷新配置文件

sysctl -p     #刷新配置文件

3、常见的内核参数优化

3.1 控制源路由验证

#Controls source route verification     控制源路由验证
net.ipv4.conf.default.rp_filter = 1
#这个参数设置的是反向路径过滤(Reverse Path Filtering,RPFilter)的策略。当rp_filter为1时,Linux内核会检查入站数据包的源IP地址是否与到达接口的路由表条目相匹配。如果源IP地址无法通过到达接口回溯到发送端,则数据包会被丢弃。启用此选项有助于防止IP地址欺骗攻击。

net.ipv4.ip_nonlocal_bind = 1
#这个参数允许或禁止非本地地址绑定到套接字。当ip_nonlocal_bind设置为1时,任何用户都可以将一个非本地IP地址(即不在本机接口上的IP地址)绑定到一个socket上。在某些场景下,例如负载均衡器或者需要绑定任意IP的代理服务器,可能需要开启这个选项。

net.ipv4.ip_forward = 1
#这个参数控制系统的IP转发功能。当ip_forward设置为1时,Linux内核将允许数据包在网络接口之间进行转发,这使得该主机可以作为路由器使用,允许其他设备通过它来传输数据包。这对于构建NAT环境、路由器和代理服务器等应用场景是必要的。关闭此选项则意味着主机仅处理发送给自身的数据包,不允许其成为网络中其他设备之间的通信桥梁。

#Do not accept source routing   不接受源路由
net.ipv4.conf.default.accept_source_route = 0
#这个设置禁止了IPv4协议栈接受源路由数据包。源路由允许数据包指定其在网络中传输的具体路径。由于这可能导致安全风险(如中间人攻击),因此默认禁用此功能以增强安全性。

3.2  控制内核的系统请求调试功能

#Controls the System Request debugging functionality of the kernel  控制内核的系统请求调试功能
kernel.sysrq = 0
#控制内核System Request (SysRq) 功能,也称为Magic SysRq Key。当值为0时,表示大部分SysRq组合键被禁用,只有少数用于紧急情况下的故障恢复操作可能仍然可用。这个设置可以防止未经授权的用户利用SysRq键进行潜在的恶意操作。

3.3  控制核心转储是否将PID附加到核心文件名

#Controls whether core dumps will append the PID to the core filename.   控制核心转储是否将PID附加到核心文件名
#Useful for debugging multi-threaded applications.   用于调试多线程应用程序
kernel.core_uses_pid = 1
#当该参数设为1时,系统在产生核心转储文件(core dump)时,会在核心文件名后附加进程ID(PID)。这对于调试多线程应用非常有用,因为它能确保来自不同进程的核心转储不会覆盖彼此,并且可以根据PID轻松区分各个转储文件

3.4 控制TCP同步cookie的使用

#Controls the use of TCP syncookies   控制TCP同步cookie的使用
net.ipv4.tcp_syncookies = 1
#这个设置启用TCP SYN Cookies功能。在受到SYN Flood攻击(一种常见的DDoS攻击形式)时,系统可能会耗尽可用的半连接队列资源。当tcp_syncookies被启用后,在半连接队列满的情况下,系统会生成一个加密的SYN cookie来响应新的SYN请求,以此避免拒绝合法的连接请求,并对部分攻击起到一定的防御作用

3.5  在网桥上禁用netfilter

#Disable netfilter on bridges.   在网桥上禁用netfilter
net.bridge.bridge-nf-call-ip6tables = 0
#这个设置禁止在网桥设备上应用ip6tables规则。这意味着任何通过该网桥的数据包将不会被IPv6防火墙规则处理。

net.bridge.bridge-nf-call-iptables = 0
#同样地,这个设置禁止在网桥设备上应用iptables规则。即,所有通过此网桥传输的IPv4数据包将不经过iptables防火墙过滤器。

net.bridge.bridge-nf-call-arptables = 0
#此设置禁用了在网桥设备上对ARP表项进行arptables规则检查。因此,所有通过该网桥的ARP流量都不会被ARP防火墙规则所影响。

3.6  控制消息队列的默认最大大小 

#Controls the default maxmimum size of a mesage queue   控制消息队列的默认最大大小
kernel.msgmnb = 65536
#这个参数设置的是消息队列的最大字节数,默认的消息队列中单个消息的最大长度。在System V IPC机制中,消息队列允许进程间传递结构化数据,这里设定了单个消息的最大大小为64KB。

#Controls the maximum size of a message, in bytes   控制消息的最大大小(以字节为单位)
kernel.msgmax = 65536
#同样与消息队列有关,这个参数也是设置单个消息的最大尺寸,单位同样是字节。当两者同时设定时,msgmax必须大于等于msgmnb,并且这里的值同样为64KB。

#Controls the maximum shared segment size, in bytes  控制最大共享段大小(以字节为单位)
kernel.shmmax = 68719476736
#这个参数定义了系统范围内共享内存段的最大大小,以字节为单位。这里设定的最大共享内存段大小为64GB,这意味着Linux系统支持的最大单一共享内存区域不能超过这个值。

#Controls the maximum number of shared memory segments, in pages   控制共享内存段的最大数目,以页为单位
kernel.shmall = 4294967296
#此参数表示系统范围内共享内存总页数的最大值(以页为单位)。由于Linux系统通常使用4KB一页(具体取决于系统配置),所以这里的4294967296页相当于16TB(4096 * 4294967296)。这个数值影响系统可以分配的共享内存总量,不过实际能使用的共享内存量还要受shmmax的限制。

3.7  调试TCP内核参数

#TCP kernel paramater   TCP内核参数
net.ipv4.tcp_mem = 786432 1048576 1572864
#这组参数定义了TCP内存使用的三个阈值(单位通常是页面数),分别为最小值、默认值和最大值。当TCP堆栈需要分配更多的内存来存储数据包时,它会根据当前的TCP内存使用量动态调整到这三个阈值之间。这有助于防止在高负载或攻击情况下耗尽系统内存。

net.ipv4.tcp_rmem = 4096        87380   4194304
#这个设置定义了接收缓冲区大小的范围。分别对应的是最小接收缓冲区大小、默认接收缓冲区大小以及最大接收缓冲区大小(单位都是字节)。较大的接收窗口可以提高网络吞吐量,但过度增加可能会导致延迟增大或者带宽浪费。

net.ipv4.tcp_wmem = 4096        16384   4194304
#类似地,这个设置定义了发送缓冲区大小的范围。最小发送缓冲区大小、默认发送缓冲区大小以及最大发送缓冲区大小(同样以字节为单位)。适当地调整发送缓冲区大小有助于平衡网络带宽利用和响应时间

net.ipv4.tcp_window_scaling = 1
#当此参数设置为1时,启用TCP窗口缩放选项。窗口缩放允许TCP连接使用超过旧版TCP规范中定义的64KB窗口限制,从而支持更大的带宽和更高的吞吐量。

net.ipv4.tcp_sack = 1
#启用选择确认(SACK)选项,SACK允许TCP发送方和接收方更精确地了解哪些数据已经正确收到,哪些数据需要重新传输。启用SACK可以改善丢包恢复效率,并在一定程度上提升带宽利用率和网络性能。

3.8  调试套接字缓冲区

#socket buffer   套接字缓冲区
net.core.wmem_default = 8388608
#这个设置定义了每个TCP套接字默认的发送缓冲区大小(单位是字节)。较大的发送缓冲区可以容纳更多的待发送数据,有助于提高带宽利用率,但也可能导致延迟增大。

net.core.rmem_default = 8388608
#这个设置设定了每个TCP套接字默认的接收缓冲区大小。更大的接收缓冲区能容纳更多等待处理的数据包,对高带宽环境下的性能优化有益。

net.core.rmem_max = 16777216
#这个值是TCP套接字接收缓冲区的最大允许大小,任何尝试设置超过这个值的操作都将被限制在此范围内。

net.core.wmem_max = 16777216
#类似地,此参数设置了TCP套接字发送缓冲区的最大可配置大小。

net.core.netdev_max_backlog = 262144
#这个参数控制了网络设备在队列满时还能临时缓存多少未处理的数据包。较高的数值意味着网络接口在处理中断和数据包转发之间可以承受更高的负载,但过高的数值可能会导致延迟增加。

net.core.somaxconn = 20480
#这个参数决定了监听套接字(如服务器端)所能接受的并发连接请求的最大数量。增加这个值可以提高服务端同时处理新连接请求的能力,但在某些情况下也可能造成资源浪费。

net.core.optmem_max = 81920
#这个设置指定了单个套接字上选项内存区域的最大大小,用于存储TCP、UDP等协议选项相关的数据结构。

 3.9 调试与TCP连接管理相关

#TCP conn   TCP连接管理相关
net.ipv4.tcp_max_syn_backlog = 262144
#这个参数设置SYN队列的大小,即半开连接队列的最大长度。当服务器收到一个SYN(同步)请求时,在收到客户端确认之前,这个连接处于半开状态并存放在SYN队列中。增大此值可以应对更大的并发SYN攻击或高负载情况下的连接建立需求,但过高可能会消耗过多内存。

net.ipv4.tcp_syn_retries = 3
#这个参数指定了在TCP三次握手过程中,服务器发送SYN-ACK后重试的次数。如果在指定次数内没有收到客户端的ACK响应,则服务器将放弃连接尝试。默认值为3次,通常不需要频繁调整。

net.ipv4.tcp_retries1 = 3
#定义了数据包在正常传输阶段(非初始连接建立阶段)丢失后的重试次数。在此阶段,如果发送的数据包未得到确认,内核会进行一定次数的重传尝试。同样,默认值通常足够使用,但在网络环境较差的情况下可能需要适当增加以提高数据传输可靠性。

net.ipv4.tcp_retries2 = 15
#类似于tcp_retries1,但这是在慢启动阶段或者拥塞避免算法触发重传时的重试次数。在网络状况不佳或存在严重丢包问题时,可能需要增大该值以保持连接稳定。

3.10 TCP连接重用 

#tcp conn reuse   TCP连接重用
net.ipv4.tcp_tw_reuse = 1
#当设置为1时,允许在TIME_WAIT状态的socket被重用来建立新的连接。这对于服务器端处理大量短连接的情况很有帮助,可以更高效地利用系统资源,减少新连接建立的时间开销。但需要注意的是,在某些NAT网络环境中启用此选项可能会导致连接混淆问题。

net.ipv4.tcp_tw_recycle = 1
#启用该选项后,Linux内核会尝试快速回收处于TIME_WAIT状态的套接字以节省资源。这同样有助于提高高并发短连接场景下的性能。然而,由于它依赖于精确的往返时间计算(RFC 1323 timestamps),在存在NAT或防火墙设备的情况下可能导致连接不稳定。因此,现代Linux内核通常不推荐使用此选项

net.ipv4.tcp_fin_timeout = 1
#启用该选项后,Linux内核会尝试快速回收处于TIME_WAIT状态的套接字以节省资源。这同样有助于提高高并发短连接场景下的性能。然而,由于它依赖于精确的往返时间计算(RFC 1323 timestamps),在存在NAT或防火墙设备的情况下可能导致连接不稳定。因此,现代Linux内核通常不推荐使用此选项

net.ipv4.tcp_max_tw_buckets = 20000
#这个参数设置系统可以同时保持的TIME_WAIT状态套接字的最大数量。当超过这个值时,旧的TIME_WAIT套接字将被强制关闭以释放资源。在高并发短连接场景下,可能需要增大此值以支持更多的并发连接。

net.ipv4.tcp_max_orphans = 3276800
#指定了系统能够接受并维护的无父进程的(即孤儿)TCP套接字的最大数量。当一个进程结束但其创建的TCP连接尚未完全关闭时,这些连接会成为孤儿套接字,由内核进行清理。如果短时间内产生大量孤儿套接字可能会耗尽资源,因此可以通过调整该参数来控制。

net.ipv4.tcp_timestamps = 1 #?
#当设置为1时,启用TCP时间戳选项(RFC 1323)。时间戳有助于更精确地计算往返时间(RTT),从而改善TCP拥塞控制和重新排序算法的表现。大多数现代网络环境都建议开启此选项。

net.ipv4.tcp_synack_retries = 1
#设置服务器在收到客户端的SYN请求后发送SYN+ACK包后的重试次数。默认情况下,服务器会尝试多次发送SYN+ACK直到收到客户端的确认。将此值设为1意味着只尝试一次,这可以减少潜在的SYN洪泛攻击的影响,但可能会降低正常连接建立的成功率。

net.ipv4.tcp_syncookies = 1
#启用TCP SYN Cookies功能,这是一种对抗SYN洪泛攻击的技术。在SYN队列满的情况下,系统将生成SYN cookie回复给客户端,避免了拒绝合法连接请求的问题。在面临大规模SYN洪泛攻击时,启用此选项非常有用。

3.11  TCP连接保活(Keepalive)和本地端口范围

#keepalive conn   TCP连接保活(Keepalive)和本地端口范围
net.ipv4.tcp_keepalive_time = 300
#这个参数设置TCP连接空闲多久后开始发送保活探测(Keepalive probes)。这里的值是300秒,意味着如果一个TCP连接在300秒内没有任何数据交换,系统将开始发送保活探测包以检查对端是否仍然在线。

net.ipv4.tcp_keepalive_intvl = 30
#定义了连续两个保活探测包之间的间隔时间。在这个例子中,每隔30秒发送一次保活探测包,直到收到对方响应或达到最大探测次数。

net.ipv4.tcp_keepalive_probes = 3
#指定在未收到任何响应时发送的最大保活探测包的数量。当系统发送3次保活探测包都没有得到回应后,会认为连接已经断开并关闭该连接。

net.ipv4.ip_local_port_range = 10001    65000
#这个参数定义了Linux系统分配给新的出站TCP/UDP连接的本地端口号范围。最小值为10001,最大值为65000,这意味着系统在这两个数值之间随机选择可用端口用于发起新的网络连接。

3.12 swap分区 

#swap   分区
vm.overcommit_memory = 0
#这个参数控制了系统对内存分配请求的处理策略。设置为0意味着系统采用保守的过载提交策略(heuristic overcommit),仅允许在物理内存加上交换空间足以满足所有已分配内存的情况下进行新的内存分配。这种设置下,虽然可能会减少意外OOM(Out of Memory)错误的发生,但也可能限制了程序利用内存的能力。

vm.swappiness = 10
#这个参数定义了Linux内核将页面从物理内存交换到交换分区(swap space)的倾向性。取值范围是0到100,默认值通常在30至60之间。值越低,表示内核更不愿意将内存页换出到交换分区;值越高,则内核更倾向于使用交换分区。这里设置为10,意味着内核相对保守地使用交换空间,尽量保持应用程序在物理内存中运行以提高性能。但请注意,对于某些内存需求波动较大的应用或系统资源紧张时,较低的swappiness设置可能导致可用内存不足的问题。

net.ipv4.conf.eth1.rp_filter = 0
#这行配置表示在eth1这个网络接口上禁用反向路径过滤(Reverse Path Filtering,RP_filter)。RP_filter是一种安全机制,用于防止IP地址欺骗。当设置为0时,系统将不对数据包的源IP地址进行严格的反向路径检查,即允许来自任何接口的数据包经过eth1接口发送出去。在某些特定情况下(如负载均衡、NAT等),可能需要禁用此功能。

net.ipv4.conf.lo.arp_ignore = 1
#设置本地回环接口(lo)的ARP忽略级别为1。这意味着对lo接口而言,只有目的IP地址匹配本机任何一个接口IP地址的数据包才会响应ARP请求。这对于防止通过lo接口对外广播ARP请求或响应是有帮助的。

net.ipv4.conf.lo.arp_announce = 2
#设置本地回环接口的ARP通告级别为2。这意味着对于从lo接口发出的ARP请求或响应,系统会尽量使用最具体的IP地址来通告。在多播路由或者有多个IP地址的情况下,这有助于减少混淆并确保正确的IP映射关系。

net.ipv4.conf.all.arp_ignore = 1
#设置本地回环接口的ARP通告级别为2。这意味着对于从lo接口发出的ARP请求或响应,系统会尽量使用最具体的IP地址来通告。在多播路由或者有多个IP地址的情况下,这有助于减少混淆并确保正确的IP映射关系。

net.ipv4.conf.all.arp_announce = 2
#同样地,将所有网络接口的ARP通告级别设为2,表明系统在所有接口上都会尽量以最具体的IP地址发出ARP请求和响应。

4、优化内核参数(nginx)

默认的Linux内核参数考虑的是最通用场景,不符合用于支持高并发访问的Web服务器的定义,根据业务特点来进行调整,当Nginx作为静态web内容服务器、反向代理或者提供压缩服务器的服务器时,内核参数的调整都是不同的,此处针对最通用的、使Nginx支持更多并发请求的TCP网络参数做简单的配置

[root@localhost ~]#vim /etc/sysctl.conf   #修改配置文件
fs.file-max = 1000000
#表示单个进程较大可以打开的句柄数
 
net.ipv4.tcp_tw_reuse = 1
#参数设置为 1 ,表示允许将TIME_WAIT状态的socket重新用于新的TCP链接,这对于服务器来说意义重大,因为总有大量TIME_WAIT状态的链接存在
 
net.ipv4.tcp_keepalive_time = 600
#当keepalive启动时,TCP发送keepalive消息的频度;默认是2小时,将其设置为10分钟,可更快的清理无效链接
 
net.ipv4.tcp_fin_timeout = 30
#当服务器主动关闭链接时,socket保持在FIN_WAIT_2状态的较大时间
 
net.ipv4.tcp_max_tw_buckets = 5000
#表示操作系统允许TIME_WAIT套接字数量的较大值,如超过此值,TIME_WAIT套接字将立刻被清除并打印警告信息,默认为8000,过多的TIME_WAIT套接字会使Web服务器变慢
 
net.ipv4.ip_local_port_range = 1024 65000
#定义UDP和TCP链接的本地端口的取值范围
 
net.ipv4.tcp_rmem = 10240 87380 12582912
#定义了TCP接受缓存的最小值、默认值、较大值
 
net.ipv4.tcp_wmem = 10240 87380 12582912
#定义TCP发送缓存的最小值、默认值、较大值
 
net.core.netdev_max_backlog = 8096
#当网卡接收数据包的速度大于内核处理速度时,会有一个列队保存这些数据包。这个参数表示该列队的较大值
 
net.core.rmem_default = 6291456
#表示内核套接字接受缓存区默认大小
 
net.core.wmem_default = 6291456
#表示内核套接字发送缓存区默认大小
 
net.core.rmem_max = 12582912
#表示内核套接字接受缓存区较大大小
 
net.core.wmem_max = 12582912
#表示内核套接字发送缓存区较大大小
注意:以上的四个参数,需要根据业务逻辑和实际的硬件成本来综合考虑
 
net.ipv4.tcp_syncookies = 1
#与性能无关。用于解决TCP的SYN攻击
 
net.ipv4.tcp_max_syn_backlog = 8192
#这个参数表示TCP三次握手建立阶段接受SYN请求列队的较大长度,默认1024,将其设置的大一些可使出现Nginx繁忙来不及accept新连接时,Linux不至于丢失客户端发起的链接请求
 
net.ipv4.tcp_tw_recycle = 1
#这个参数用于设置启用timewait快速回收
 
net.core.somaxconn=262114
#选项默认值是128,这个参数用于调节系统同时发起的TCP连接数,在高并发的请求中,默认的值可能会导致链接超时或者重传,因此需要结合高并发请求数来调节此值。
 
net.ipv4.tcp_max_orphans=262114
#选项用于设定系统中最多有多少个TCP套接字不被关联到任何一个用户文件句柄上。如果超过这个数字,孤立链接将立即被复位并输出警告信息。这个限制指示为了防止简单的DOS攻击,不用过分依靠这个限制甚至认为的减小这个值,更多的情况是增加这个值