Linux 参数调优
一、TCP
1. 三次握手
2. 四次挥手
3. TCP连接
A. 系统只有65535个端口可用,而1024以下的端口为系统保留,那么真正可用端口为65411个;
B. 一个TCP连接由TCP四元组(源IP、源端口、目标IP、目标端口)唯一确定,故一个网卡最多只能打开65411个TCP连接,承载更多并发就需要加网卡(包括虚拟网卡)或机器;
4. TCP半连接队列(Syns Queue)
A. 服务端收到客户端发起的SYN请求后,内核会把该连接存储到半连接队列,并向客户端响应SYN+ACK包;
B. 当超过了TCP半连接队列大小后,服务端则会丢掉后续进来的TCP连接,丢掉的个数可以使用netstat -s | grep 'SYNs'查看,SYNs前面值表示溢出的次数累计值,如果间隔观察还持续增加,则要调大半连接队列值了;
C. 半连接队列大小:不同内核版本计算方式不同,大概是取min(应用服务器backlog,内核参数net.core.somaxconn,内核参数tcp_max_syn_backlog) * 2,感兴趣可以发起SYN攻击测试及查看内核源码;
5. TCP全连接队列(accept queue)
A. 客户端收到服务端SYN+ACK包后,会返回ACK包,而服务端收到第三次握手的ACK后,内核会把连接从半连接队列移除,然后创建新的完全的连接,并将其添加到accept队列,等待进程调用accept函数时会把连接取出来;
B. 当超过了TCP全连接队列大小后,服务端则会丢掉后续进来的TCP连接,丢掉的个数可以使用netstat -s | grep 'overflowed'查看,times前面值表示溢出的次数累计值,如果间隔观察还持续增加,则要调大全连接队列值了;
C. 全连接队列大小:min(应用服务器backlog,内核参数net.core.somaxconn),其中backlog对应nginx服务器默认值是511、Tomcat默认值是200,somaxconn默认值是128;
二、命令
1. 查看TCP连接各状态的数量:netstat -n | awk '/^tcp/ {++S[$NF]} END { for(a in S) print a, S[a]}';
LISTEN:服务器需要打开一个socket进行监听的状态;
SYN_SEND:客户端TCP发送一个SYN以请求建立一个连接的状态;
SYN_RECV:服务端应发出ACK确认客户端的SYN,同时自己向客户端发送一个SYN之后的状态;
ESTABLISHED:代表一个打开的连接,双方可以进行或者已经在交互数据了;
FIN_WAIT2:在主动关闭端接收到ACK后,就进入FIN_WAIT2的状态,属于客户端的状态;
TIME_WAIT:在主动关闭端接收到FIN后,TCP就发送ACK包,并进入TIME_WAIT状态,属于客户端的状态;
2. netstat命令
A. 查看TCP连接的半连接队列满而被丢弃的个数:netstat -s | grep "SYNs to LISTEN";
B. 查看TCP连接的全连接队列(accept)满而被丢弃的个数:netstat -s | grep overflowed;
C. 查看当前处于半连接状态的连接个数:netstat -napt | grep SYN_RECV | wc -l。
D. 全连接队列查看:ss -lnt
LISTEN状态下:Recv-Q值表示当前全连接队列大小,也就是当前已经完成三次握手并等待服务端调用accept函数的TCP连接,Send-Q值表示全连接队列最大长度;
EATABLISHED状态下:Recv-Q值表示已收到但未被应用程序读取的字节数,Send-Q值表示已发送但未收到确认的字节数。
三、Linux内核参数
参数 | 默认值 | 描述 | 备注 |
net.ipv4.tcp_syn_retries | 5 | 表示对于一个新建连接,内核要发送多少个SYN连接请求才决定放弃 | 每次重传的时间是上次的两倍,比如第一次是1s后,第二是2s后,第三次是4s后,故终止连接耗时63s |
net.ipv4.tcp_synack_retries | 5 | 表示对于客户端发送SYN的连接,内核要发送多少个SYN+ACK报文才决定放弃 | 每次重传的时间是上次的两倍,比如第一次是1s后,第二是2s后,第三次是4s后,故终止连接耗时63s |
net.ipv4.tcp_syncookies | 0(0->否、1->是) | 表示是否打开TCP同步标签,内核必须开启并编译CONFIG_SYN_COOKIES才会生效,可以防止syn flood攻击 | 参数值设为1,且SYN_RECV 队列满了之后,内核会对SYN包的回复做一定的修改,即在响应的SYN+ACK包中,初始的序列号是由源IP+Port、目的IP+Port及时间这五个参数共同计算出一个值组成精心组装的TCP包。由于ACK包中确认的序列号并不是之前计算出的值,恶意攻击者无法响应或误判,而请求者会根据收到的SYN+ACK包做正确的响应。启用net.ipv4.tcp_syncookies 后,会忽略net.ipv4.tcp_max_syn_backlog |
net.ipv4.tcp_tw_reuse | 0(0->否、1->是) | 表示是否允许将处于TIME-WAIT状态的Socket用于新的TCP连接 | 值设置为1,如果新请求的时间戳,比存储的时间戳更大,则系统将会从TIME_WAIT状态的存活连接中选取一个,重新分配给新的请求连接 |
net.ipv4.tcp_tw_recycle | 0(0->否、1->是) | 表示是否打开快速的回收TIME-WAIT状态的Socket | 值设置为1,开启TCP连接中TIME-WAIT的sockets快速回收功能。需要注意的是,该机制也依赖时间戳选项,系统默认开启tcp_timestamps机制,而当系统中的tcp_timestamps和tcp_tw_recycle机制同时开启时,会激活TCP的一种行为,即缓存每个连接最新的时间戳,若后续的请求中时间戳小于缓存的时间戳时,该请求会被视为无效,导致数据包会被丢弃。特别是作为负载均衡服务器的场景,不同客户端请求经过负载均衡服务器的转发,可能被认为是同一个连接,若客户端的时间不一致,对于后端服务器来说,会发生时间戳错乱的情况,因此会导致数据包丢失,从而影响业务 |
net.ipv4.tcp_fin_timeout | 60,单位为秒 | 对于本端断开的Socket连接,TCP保持在FIN-WAIT-2状态的时间(秒),对方可能会断开连接或一直不结束连接或不可预料的进程死亡 | |
net.ipv4.tcp_keepalive_time | 7200,单位为秒 | TCP发送keepalive探测消息的间隔时间(秒),用于确认TCP连接是否有效 | |
net.ipv4.tcp_keepalive_probes | 9 | TCP发送keepalive探测消息的间隔时间(秒),用于确认TCP连接是否有效 | |
net.ipv4.tcp_keepalive_intvl | 75,单位为秒 | 探测消息未获得响应时,重发该消息的间隔时间(秒)。默认值为75秒。 (对于普通应用来说,这个值有一些偏大,可以根据需要改小.特别是web类服务器需要改小该值,15是个比较合适的值) |
# 内存分配,值为0、1、2,1表示内核允许超量使用内存直到用完位置,通常Redis等内存操作需要设置为1 vm.overcommit_memory=1
# 表示尽量使用内存,减少使用磁盘swap交换分区,默认值为60
vm.swappiness=0
# 用来限制监听(LISTEN)队列最大数据包的数量,超过这个数量就会导致链接超时或者触发重传机制
net.core.somaxconn=4096
# TCP发送keepalive探测消息的间隔时间,用于确认TCP连接是否有效
net.ipv4.tcp_keepalive_time=7200
sysctl -p 使配置生效
四、文件描述符(file descriptor)
1. 概念:在Linux系统中一切皆是文件,文件描述符是内核为了高效管理已被打开的文件所创建的索引,文件描述限制分为系统级限制和用户级限制;
2. 系统级限制
A. 定义:系统内核最大打开文件数量,理论上系统内存有多少就可以打开多少文件描述符,但一般限制为系统的内存10%;
B. 命令查看:sysctl -a | grep fs.file-max;
C. 修改限制:vim /etc/sysctl.conf,添加fs.file-max=400000,使用sysctl -p生效。
3. 用户级限制
A. 定义:单个进程最大打开文件数量,内核为了不让某一进程消耗掉所有的文件资源,一般限制为1024;
B. 命令查看:ulimit -a;
C. 修改限制:vim /etc/security/limits.conf,添加如下内容,保存后,重新打开会话生效。
1 2 3 | # *代表所有用户生效,soft软限制,超过警告,hard实际限制,nofile文件句柄参数,65536最大文件句柄数设置<br>* soft nofile 65536 * hard nofile 65536 |
五、Linux手动清理缓存drop_caches
1. 基础:free命令用于查看系统实际使用内存的情况,如:free -h,单位显示为M,命令行显示的buffer/cache都是页缓存;
top命令可以查看各个进程的情况,默认按照CPU的使用率排序,通过"shift+m"按键将进程按照内存使用情况排序,其中RES:常驻内存,是进程切实使用的物理内存量,单位KiB,%MEM:占用内存百分比。
2. drop_caches介绍:Linux本身也有内存回收机制,但同时也提供了一种手动释放的方法,就是设置/proc/sys/vm/drop_caches参数,用于回收缓存及清理可回收对象,该参数总共三个数字值;
A. 1:只清理页缓存(pagecache);
B. 2:只清理可回收对象;
C. 3:清理pagecache和可回收对象,如:echo 3 > /proc/sys/vm/drop_caches;
回收内存操作并非破坏性操作,不放释放任何脏数据,如果需要增加被释放的对象,需要运行sync命令,设置此drop_caches参数可能导致系统性能下降,主要是由于他丢弃了一部分缓存对象,导致频繁地与磁盘进行交互;
3. crontab定时清理linux缓存free.sh
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | #! /bin/sh used=` free -m | awk 'NR==2' | awk '{print $3}' ` free =` free -m | awk 'NR==2' | awk '{print $4}' ` echo "===========================" >> . /mem .log echo "Memory usage before | [Use:${used}MB][Free:${free}MB]" >> . /mem .log if [ $ free - le 1000000 ] ; then sync && echo 1 > /proc/sys/vm/drop_caches sync && echo 2 > /proc/sys/vm/drop_caches sync && echo 3 > /proc/sys/vm/drop_caches used_ok=` free -m | awk 'NR==2' | awk '{print $3}' ` free_ok=` free -m | awk 'NR==2' | awk '{print $4}' ` echo "Memory usage after | [Use:${used_ok}MB][Free:${free_ok}MB]" >> . /mem .log echo "OK" >> . /mem .log else echo "Not required" >> . /mem .log fi exit 1 |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 通过 API 将Deepseek响应流式内容输出到前端
· AI Agent开发,如何调用三方的API Function,是通过提示词来发起调用的吗
2020-01-14 Elasticsearch 集群Cluster API(7.5.0)