Linux内核优化
文章目录
一、优化文件打开数和打开系统进程数
1、打开文件最大数临时设置方法
2、文件描述符
二、TCP的三次握手和四次断开
三、内核参数优化
1、BAT企业生产环境内核完整参数
2、Linux内核常见参数详解
3、Linux内核常用参数详解
四、Linux内核报错剖析
1、time wait bucket overflow错误
2、Too many open files错误
3、DDOS攻击防护:possible SYN fiooding on port 80. Sending cookies 错误
一、优化文件打开数和打开系统进程数
为了防止失控的进程破坏系统的性能,Unix和Linux会跟踪进程使用的大部分资源,会对用户及系统管理员进行资源限制,例如控制某个打开文件最大数、最某个用户打开进程数进行限制等,一般限制手段包括:软限制和硬限制
注:软限制并没有太多的用,一般这两者的值都是相等的。
1、打开文件最大数临时设置方法:
重启服务该参数无效,命令行终端执行如下命令:
ulimit -n 65535
永久设置方法
将如下代码加入内核限制文件/etc/security/limits.conf的末尾:
* soft noproc 65535 * hard noproc 65535 * soft nofile 65535 * hard nofile 65535
如果需要对Linux整个系统设置文件最大数限制,需要修改/proc/sys/fs/file-max中的值,该值为Linux总文件打开数,例如设置为:echo 3865161233 >/proc/sys/fs/file-max。
"*"表示所有用户。如果改成root就表示对root用户的限制。
2、文件描述符
我们打开一个服务,会起很多进程,进程又会打开很多的文件,比如服务配置文件、日志文件等等,<font color=red>文件描述符便是内核为了高效管理已被打开的文件所创建的索引。</font>
我们现在看下nginx主进程的所有文件描述符:
注:文件描述符是非负小整数!
扩展知识(非重点):
Linux系统为每个进程维护了一个文件描述符,该表的值都是从0 开始的,在不同的进程中你会看到相同的文件描述符。相同问价描述符有可能指向不同的文件。Linux内核文件操作,维护了3个数据结构概念如下:
1、进程级的文件描述符表;
2、系统级的打开文件描述符表;
3、文件系统的i-node表;
二、TCP的三次握手和四次断开
使用tcpdump抓包分析:
确保自己的Nginx已经成功部署!
tcpdump -i ens33 -nn host 172.16.193.201 and port 80 #抓取所有经过ens33,目的或源地址:端口是172.16.193.201:80的网络数据 -i:指定本地监控的网络接口 -n:对地址以数字方式显式,否则显式为主机名; -nn:除了-n的作用外,还把端口显示为数值,否则显示端口服务名;
访问一下nginx
三次握手:
四次断开
三、内核参数优化
Linux/porc/sys 目录下存放着多数内核的参数,并且可以在系统允许时进行更改,一般重新启动机器就会失效;/porc/sys下内核文件与配置文件/etc/sysctl.conf中变量存在着对应关系,即修改sysctl.conf配置文件,其实是修改/porc/sys相关参数!
1、BAT企业生产环境内核完整参数:
net.ipv4.ip_forward = 0 net.ipv4.conf.default.rp_filter = 1 net.ipv4.conf.default.accept_source_route = 0 kernel.sysrq = 0 kernel.core_uses_pid = 1 net.ipv4.tcp_syncookies = 1 kernel.msgmnb = 65536 kernel.msgmax = 65536 kernel.shmmax = 68719476736 kernel.shmall = 4294967296 net.ipv4.tcp_max_tw_buckets = 10000 net.ipv4.tcp_sack = 1 net.ipv4.tcp_window_scaling = 1 net.ipv4.tcp_rmem = 4096 87380 4194304 net.ipv4.tcp_wmem = 4096 16384 4194304 net.core.wmem_default = 8388608 net.core.rmem_default = 8388608 net.core.rmem_max = 16777216 net.core.wmem_max = 16777216 net.core.netdev_max_backlog = 262144 net.core.somaxconn = 262144 net.ipv4.tcp_max_orphans = 3276800 net.ipv4.tcp_max_syn_backlog = 262144 net.ipv4.tcp_timestamps = 0 net.ipv4.tcp_synack_retries = 1 net.ipv4.tcp_syn_retries = 1 net.ipv4.tcp_tw_recycle = 1 net.ipv4.tcp_tw_reuse = 1 net.ipv4.tcp_mem = 94500000 915000000 927000000 net.ipv4.tcp_fin_timeout = 1 net.ipv4.tcp_keepalive_time = 30 net.ipv4.ip_local_port_range = 1024 65535
2、Linux内核常见参数详解
net.ipv4.tcp_timestamps = 1 //该参数控制RFC 1323 时间戳与窗口缩放选项; net.ipv4.tcp_sack = 1 //选择性应答(SACK)是 TCP 的一项可选特性,可以提高某些网络中所有可用带宽的使用效率; net.ipv4.tcp_fack = 1 //打开FACK(Forward ACK) 拥塞避免和快速重传功能; net.ipv4.tcp_retrans_collapse = 1 //打开重传重组包功能,为0的时候关闭重传重组包功能; net.ipv4.tcp_syn_retries = 5 //对于一个新建连接,内核要发送多少个SYN 连接请求才决定放弃; net.ipv4.tcp_synack_retries = 5 tcp_synack_retries //显示或设定Linux在回应SYN要求时尝试多少次重新发送初始SYN,ACK封包后才决定放弃; net.ipv4.tcp_max_orphans = 131072 //系统所能处理不属于任何进程的TCP sockets最大数量; net.ipv4.tcp_max_tw_buckets = 5000//系统同时保持TIME_WAIT套接字的最大数量,如果超过这个数字,TIME_WAIT套接字将立刻被清除并打印警告信息;默认为180000,设为较小数值此项参数可以控制TIME_WAIT套接字的最大数量,避免服务器被大量的TIME_WAIT套接字拖死; net.ipv4.tcp_keepalive_time = 30 net.ipv4.tcp_keepalive_probes = 3 net.ipv4.tcp_keepalive_intvl = 3 //如果某个TCP连接在空闲30秒后,内核才发起probe(探查); //如果probe 3次(每次3秒既tcp_keepalive_intvl值)不成功,内核才彻底放弃,认为该连接已失效; net.ipv4.tcp_retries1 = 3 //放弃回应一个TCP 连接请求前﹐需要进行多少次重试; net.ipv4.tcp_retries2 = 15 //在丢弃激活(已建立通讯状况)的TCP连接之前﹐需要进行多少次重试; net.ipv4.tcp_fin_timeout = 30 //表示如果套接字由本端要求关闭,这个参数决定了它保持在 FIN-WAIT-2状态的时间; net.ipv4.tcp_tw_recycle = 1 //表示开启TCP连接中TIME-WAIT sockets的快速回收,默认为0,表示关闭; net.ipv4.tcp_max_syn_backlog = 8192 //表示SYN队列的长度,默认为1024,加大队列长度为8192,可以容纳更多等待连接的网络连接数; net.ipv4.tcp_syncookies = 1 //TCP建立连接的 3 次握手过程中,当服务端收到最初的 SYN 请求时,会检查应用程序的syn_backlog队列是否已满,启用syncookie,可以解决超高并发时的Can’t Connect` 问题。但是会导致 TIME_WAIT 状态fallback为保持2MSL时间,高峰期时会导致客户端无可复用连接而无法连接服务器; net.ipv4.tcp_orphan_retries = 0 //关闭TCP连接之前重试多少次; net.ipv4.tcp_mem = 178368 237824 356736 net.ipv4.tcp_mem[0]: //低于此值,TCP没有内存压力; net.ipv4.tcp_mem[1]: //在此值下,进入内存压力阶段; net.ipv4.tcp_mem[2]: //高于此值,TCP拒绝分配socket; net.ipv4.tcp_tw_reuse = 1 //表示开启重用,允许将TIME-WAIT sockets重新用于新的TCP连接; net.ipv4.ip_local_port_range = 1024 65000 //表示用于向外连接的端口范围; net.ipv4.ip_conntrack_max = 655360 //在内核内存中netfilter可以同时处理的“任务”(连接跟踪条目); net.ipv4.icmp_ignore_bogus_error_responses = 1 //开启恶意icmp错误消息保护; net.ipv4.tcp_syncookies = 1 //开启SYN洪水攻击保护。
3、Linux内核常用参数详解
net.ipv4.tcp_sack = 1 //选择性应答(SACK)是 TCP 的一项可选特性,可以提高某些网络中所有可用带宽的使用效率; net.ipv4.tcp_fack = 1 //打开FACK(Forward ACK) 拥塞避免和快速重传功能; net.ipv4.tcp_syn_retries = 5 //对于一个新建连接,内核要发送多少个SYN 连接请求才决定放弃; net.ipv4.tcp_synack_retries = 5 //tcp_synack_retries显示或设定Linux在回应SYN要求时尝试多少次重新发送初始SYN,ACK封包后才决定放弃; net.ipv4.tcp_max_tw_buckets = 5000//系统同时保持TIME_WAIT套接字的最大数量,如果超过这个数字,TIME_WAIT套接字将立刻被清除并打印警告信息;默认为180000,设为较小数值此项参数可以控制TIME_WAIT套接字的最大数量,避免服务器被大量的TIME_WAIT套接字拖死; net.ipv4.tcp_keepalive_time = 30 net.ipv4.tcp_keepalive_probes = 3 net.ipv4.tcp_keepalive_intvl = 3 //如果某个TCP连接在空闲30秒后,内核才发起probe(探查); //如果probe 3次(每次3秒既tcp_keepalive_intvl值)不成功,内核才彻底放弃,认为该连接已失效; net.ipv4.tcp_fin_timeout = 30 //表示如果套接字由本端要求关闭,这个参数决定了它保持在 FIN-WAIT-2状态的时间; net.ipv4.tcp_tw_recycle = 1 //表示开启TCP连接中TIME-WAIT sockets的快速回收,默认为0,表示关闭; net.ipv4.tcp_syncookies = 1//TCP建立连接的 3 次握手过程中,当服务端收到最初的 SYN 请求时,会检查应用程序的syn_backlog队列是否已满,启用syncookie,可以解决超高并发时的Can’t Connect` 问题。但是会导致 TIME_WAIT 状态fallback为保持2MSL时间,高峰期时会导致客户端无可复用连接而无法连接服务器; net.ipv4.tcp_orphan_retries = 0 //关闭TCP连接之前重试多少次; net.ipv4.tcp_tw_reuse = 1 //表示开启重用,允许将TIME-WAIT sockets重新用于新的TCP连接; net.ipv4.ip_local_port_range = 1024 65000 //表示用于向外连接的端口范围; net.ipv4.ip_conntrack_max = 655360 //在内核内存中netfilter可以同时处理的“任务”(连接跟踪条目); net.ipv4.tcp_syncookies = 1 //开启SYN洪水攻击保护。
四、Linux内核报错剖析
1、time wait bucket table overflow错误
Sep 23 04:45:55 localhost kernel: TCP: time wait bucket table overflow Sep 23 04:45:55 localhost kernel: TCP: time wait bucket table overflow Sep 23 04:45:55 localhost kernel: TCP: time wait bucket table overflow Sep 23 04:45:55 localhost kernel: TCP: time wait bucket table overflow Sep 23 04:45:55 localhost kernel: TCP: time wait bucket table overflow Sep 23 04:45:55 localhost kernel: TCP: time wait bucket table overflow
根据TCP协议定义的3次握手及四次断开连接规定,发起socket主动关闭的一方Socket将进入TIME_WAIT状态,TIME_WAIT状态将持续2个MSL(Max Segment Lifetime)。
net.ipv4.tcp_max_tw_buckets值设置过小导致,当系统Time wait数量超过默认设置的值,即会抛出如上的警告信息,需要增加net.ipv4.tcp_max_tw_buckets的值,警告信息消除。
当然也不能设置过大,对于一个处理大量短连接的服务器,如果是由服务器主动关闭客户端的连接,将导致服务器端存在大量的处于TIME_WAIT状态的Socket,甚至比处于Established状态下的Socket多的多,严重影响服务器的处理能力,甚至耗尽可用的Socket而停止服务,TIME_WAIT是TCP协议用以保证被重新分配的Socket不会受到之前残留的延迟重发报文影响的机制,是TCP传输必要的逻辑保证。
2、Too many open files错误
Benchmarking localhost (be patient) socket: Too many open files (24) socket: Too many open files (24) socket: Too many open files (24) socket: Too many open files (24) socket: Too many open files (24)
将如下代码加入内核限制文件/etc/security/limits.conf,重启服务器生效!
* soft noproc 65535 * hard noproc 65535 * soft nofile 65535 * hard nofile 65535
3、DDOS工具防护:possible SYN flooding on port 80. Sending cookies.错误
May 31 14:20:14 localhost kernel: possible SYN flooding on port 80. Sending cookies. May 31 14:21:28 localhost kernel: possible SYN flooding on port 80. Sending cookies. May 31 14:22:44 localhost kernel: possible SYN flooding on port 80. Sending cookies. May 31 14:25:33 localhost kernel: possible SYN flooding on port 80. Sending cookies. May 31 14:27:06 localhost kernel: possible SYN flooding on port 80. Sending cookies. May 31 14:28:44 localhost kernel: possible SYN flooding on port 80. Sending cookies. May 31 14:28:51 localhost kernel: possible SYN flooding on port 80. Sending cookies. May 31 14:31:01 localhost kernel: possible SYN flooding on port 80. Sending cookies.
此问题是由于SYN队列已满,而触发SYN cookies,一般是由于大量的访问,或者恶意访问导致,也称之为 SYN Flooding洪水攻击。它是DDOS攻击中的一种。
防护DDOS攻击有两种手段,一种基于硬件专业防火墙、二是基于Linux内核简单防护,如果工具流量特别大,单纯配置内核参数是无法抵挡的,还得依靠专业级硬件防火墙,
如下为Linux内核防护DDOS优化参数,加入如下代码即可:
net.ipv4.tcp_fin_timeout = 30 net.ipv4.tcp_keepalive_time = 1200 net.ipv4.tcp_syncookies = 1 net.ipv4.tcp_tw_reuse = 1 net.ipv4.tcp_tw_recycle = 1 net.ipv4.ip_local_port_range = 1024 65000 net.ipv4.tcp_max_syn_backlog = 8192 net.ipv4.tcp_max_tw_buckets = 8000 net.ipv4.tcp_synack_retries = 2 net.ipv4.tcp_syn_retries = 2