Pages

Tuesday, 17 March 2020

Linux内核调优

一、优化文件打开数和打开系统进程数

为了防止失控的进程破坏系统的性能,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。

2、文件描述符

我們打開一個服務,會起很多進程,進程又會打開很多的文件,比如服務配置文件、日誌文件等等,<font color=red>文件描述符便是內核爲了高效管理已被打開的文件所創建的索引。</font>
我们现在看下nginx主进程的所有文件描述符:
在这里插入图片描述在这里插入图片描述注:文件描述符是非负小整数!

扩展知识(非重点):
Linux系统为每个进程维护了一个文件描述符表,该表的值都从0开始的,在不同的进程中你会看到相同的文件描述符,相同文件描述符有可能指向同一个文件,也有可能指向不同的文件。Linux内核对文件操作,维护了3个数据结构概念如下:
  •  进程级的文件描述符表;
  •  系统级的打开文件描述符表;
  •  文件系统的i-node表;
三者之间的区别请自行google搜索!

二、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 /proc/sys目录下存放着多数内核的参数,并且可以在系统运行时进行更改,一般重新启动机器就会失效;/proc/sys下内核文件与配置文件/etc/sysctl.conf中变量存在着对应关系,即修改sysct.conf配置文件,其实是修改/proc/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
from https://blog.csdn.net/weixin_44571270/article/details/104879180https://www.twblogs.net/a/5e7013d7bd9eee2117c76133