1. TCP/IP报文详解
TCP/IP 定义了电子设备如何连入因特网 ,以及数据如何在它们之间传输的标准 。协议采用了4层的层级结构 ,每一层都呼叫它的下一层所提供的协议来完成自己的需求。 TCP负责发现传输的问题,一有问题就发出信号,要求重新传输,直到所有数据安全正确地传输到目的地 ,而IP是给因特网的每台联网设备规定一个地址。TCP/IP 协议数据封装的过程包括:用户数据经过应用层协议封装后传递给传输层,传输层封装TCP头部,交给网络层,网络层封装IP头部后,再交给数据链路层,数据链路层封装Ethernet帧头和帧尾,交给物理层,物理层以比特流的形式将数据发送到物理线路上 。一般而言,不同的协议层对数据包有不同的称谓,数据包在传输层叫做段(segment),在网络层叫做数据报(datagram),在链路层叫做帧(frame) 。数据封装成帧后发到传输介质上,到达目的主机后每层协议再剥掉相应的首部,最后将应用层数据交给应用程序处理,如图所示: 优化Linux服务器,需要了解TCP协议相关信息,例如TCP/IP数据报文的内容及如何传输的,如图所示为IP数据包报文详细结构图: IP数据包详解如下:
名称 解释 Source Port和Destination Port 分别占用16位,表示源端口号和目的端口号 ;用于区别主机中的不同进程,而IP地址是用来区分不同的主机的,源端口号和目的端口号配合上IP首部中的源IP地址和目的IP地址就能唯一的确定一个TCP连接Sequence Number 用来标识从TCP发端向TCP收端发送的数据字节流 ,它表示在这个报文段中的的第一个数据字节在数据流中的序号;主要用来解决网络报乱序的问题Acknowledgment Number 32位确认序列号包含发送确认的一端所期望收到的下一个序号 ,因此,确认序号应当是上次已成功收到数据字节序号Seq加1。不过,只有当标志位中的ACK标志(下面介绍)为1时该确认序列号的字段才有效。主要用来解决不丢包的问题;ACK= seq + 1Offset 给出首部中32 bit字的数目,需要这个值是因为任选字段的长度是可变的。这个字段占4bit (最多能表示15个32bit的的字,即4*15=60个字节的首部长度),因此TCP最多有60字节的首部。然而,没有任选字段,正常的长度是20字节TCP Flags TCP首部中有6个标志比特,它们中的多个可同时被设置为1,主要是用于操控TCP的状态机的,依次为URG,ACK,PSH,RST,SYN,FIN URG 此标志表示TCP包的紧急指针域(后面马上就要说到)有效,用来保证TCP连接不被中断,并且督促中间层设备要尽快处理这些数据 ACK 此标志表示应答域有效 ,就是说前面所说的TCP应答号将会包含在TCP数据包中;有两个取值:0和1,为1的时候表示应答域有效,反之为0 PSH 这个标志位表示Push操作 。所谓Push操作就是指在数据包到达接收端以后,立即传送给应用程序,而不是在缓冲区中排队 RST 这个标志表示连接复位请求 。用来复位那些产生错误的连接,也被用来拒绝错误和非法的数据包 SYN 表示同步序号,用来建立连接 。SYN标志位和ACK标志位搭配使用,当连接请求的时候,SYN=1,ACK=0;连接被响应的时候,SYN=1,ACK=1;这个标志的数据包经常被用来进行端口扫描。扫描者发送一个只有SYN的数据包,如果对方主机响应了一个数据包回来 ,就表明这台主机存在这个端口;但是由于这种扫描方式只是进行TCP三次握手的第一次握手,因此这种扫描的成功表示被扫描的机器不很安全,一台安全的主机将会强制要求一个连接严格的进行TCP的三次握手FIN 表示发送端已经达到数据末尾,也就是说双方的数据传送完成,没有数据可以传送了,发送FIN标志位的TCP数据包后,连接将被断开。这个标志的数据包也经常被用于进行端口扫描 Window: 窗口大小,也就是有名的滑动窗口,用来进行流量控制
2. TCP三次握手及四次断开
TCP是面向连接的,无论哪一方向另一方发送数据之前,都必须先在双方之间建立一条连接。在TCP/IP协议中,TCP协议提供可靠的连接服务,连接是通过三次握手进行初始化的。三次握手的目的是同步连接双方的序列号和确认号并交换TCP窗口大小信息。如图所示:
2.1. TCP三次握手原理
第一次握手:建立连接。客户端发送连接请求报文段,将SYN位置为1,Sequence Number为x;然后客户端进入SYN_SENT状态,等待服务器的确认; 第二次握手:服务器收到SYN报文段。服务器收到客户端的SYN报文段,需要对这个SYN报文段进行确认,设置Acknowledgment Number为x+1(Sequence Number+1);同时,自己自己还要发送SYN请求信息,将SYN位置为1,Sequence Number为y;服务器端将上述所有信息放到一个报文段(即SYN+ACK报文段)中,一并发送给客户端,此时服务器进入SYN_RECV状态; 第三次握手:客户端收到服务器的SYN+ACK报文段。然后将Acknowledgment Number设置为y+1或者1,向服务器发送ACK报文段,这个报文段发送完毕以后,客户端和服务器端都进入ESTABLISHED状态,完成TCP三次握手 如图所示为基于tcpdump抓取TCP/IP三次握手及数据包传输过程:
2.2. TCP四次挥手原理
第一次挥手:主机A(可以使客户端,可以是服务器端),设置Sequence Number和Acknowledgment Number,向主机B发送一个FIN报文段;此时,主机A进入FIN_WAIT_1状态;这表示主机A没有数据要发送给主机B; 第二次挥手:主机B收到了主机A发送的FIN报文段,向主机A回一个ACK报文段,Acknowledgment Number为Sequence Number加1;主机A进入FIN_WAIT_2状态;主机B告诉主机A,我“同意”你的关闭请求; 第三次挥手:主机B向主机A发送FIN报文段,请求关闭连接,同时主机B进入LAST_ACK状态; 第四次挥手:主机A收到主机B发送的FIN报文段,向主机B发送ACK报文段,然后主机A进入TIME_WAIT状态;主机B收到主机A的ACK报文段以后,就关闭连接;此时,主机A等待2MSL后依然没有收到回复,则证明Server端已正常关闭,那好,主机A也可以关闭连接。 如图所示为基于tcpdump抓取TCP/IP四次挥手及数据包传输过程:
3. 优化Linux文件打开最大数
进程级的文件描述符表; 系统级的打开文件描述符表; 文件系统的i-node表;
其中进程级的描述符表的每一个条目记录了单个文件描述符的相关信息,例如控制文件描述符操作的一组标志及对打开文件句柄的引用。Linux内核对所有打开的文件都维护了一个系统级的描述符表(open file description table)。将描述符表中的记录行称为打开文件句柄(open file handle),一个打开文件句柄存储了与一个打开文件相关的全部信息,详细信息如下:
当前文件偏移量 打开文件时所使用的状态标识 文件访问模式 与信号驱动相关的设置 对该文件i-node对象的引用 文件类型和访问权限 指针,指向该文件所持有的锁列表 文件的各种属性
默认Linux内核对每个用户设置了打开文件最大数为1024,对于高并发网站,是远远不够的,需要将默认值调整到更大,调整方法有两种: Linux每个用户打开文件最大数临时设置方法,重启服务器该参数无效,命令行终端执行如下命令:
[ root@node1 ~]
[ root@node1 ~]
65535
inux每个用户打开文件最大数永久设置方法,将如下代码加入内核限制文件/etc/security/limits.conf的末尾:
[ root@node1 ~]
在末尾添加下面内容
* soft noproc 65535
* hard noproc 65535
* soft nofile 65535
* hard nofile 65535
如上设置为对每个用户分别设置nofile、noproc最大数,如果需要对Linux整个系统设置文件最大数限制,需要修改/proc/sys/fs/file-max中的值,该值为Linux总文件打开数,例如设置为:
echo 3865161233 > /proc/sys/fs/file-max
4. 内核参数的优化
Linux /proc/sys目录下存放着多数内核的参数,并且可以在系统运行时进行更改,一般重新启动机器就会失效。而/etc/sysctl.conf是一个允许改变正在运行中的Linux系统的接口,它包含一些TCP/IP堆栈和虚拟内存系统的高级选项,修改内核参数永久生效。 /proc/sys下内核文件与配置文件sysctl.conf中变量存在着对应关系,即修改sysct.conf配置文件,其实是修改/proc/sys相关参数,所以对Linux内核优化只需修改/etc/sysctl.conf文件即可。如下为BAT企业生产环境
/etc/sysct.conf内核完整参数:
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
4.1. 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 = 1 放弃回应一个TCP 连接请求前﹐需要进行多少次重试 net.ipv4.tcp_retries2 = 1 在丢弃激活(已建立通讯状况)的TCP连接之前﹐需要进行多少次重试 net.ipv4.tcp_fin_timeout = 1 表示如果套接字由本端要求关闭,这个参数决定了它保持在 FIN-WAIT-2状态的时间 net.ipv4.tcp_tw_recycle = 1 表示开启TCP连接中TIME-WAIT sockets的快速回收,默认为0,表示关闭 net.ipv4.tcp_max_syn_backlog = 40000 表示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洪水攻击保护
5. Linux内核报错剖析
企业生产环境Linux服务器正常运行,由于某种原因会导致内核报错或者抛出很多信息,根据系统SA可以快速定位Linux服务器故障,Linux内核日志一般存在messages日志中,可以通过命令tail -fn 100 /var/log/messages查看Linux内核日志,如下为Linux内核常见报错日志及生产环境解决报错的方案:
5.1. Linux内核抛出net.ipv4.tcp_max_tw_buckets错误
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
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) 如果该值设置过小导致,当系统Time wait数量超过默认设置的值,即会抛出如上的警告信息,需要增加net.ipv4.tcp_max_tw_buckets的值,警告信息消除。 当然也不能设置过大,对于一个处理大量短连接的服务器,如果是由服务器主动关闭客户端的连接,将导致服务器端存在大量的处于TIME_WAIT状态的Socket,甚至比处于Established状态下的Socket多的多,严重影响服务器的处理能力,甚至耗尽可用的Socket而停止服务,TIME_WAIT是TCP协议用以保证被重新分配的Socket不会受到之前残留的延迟重发报文影响的机制,是TCP传输必要的逻辑保证。
5.2. Linux内核抛出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 )
每个文件描述符与一个打开文件相对应,不同的文件描述符可以指向同一个文件。相同的文件可以被不同的进程打开,也可以在同一个进程中被多次打开。Linux内核对应每个用户打开的文件最大数一般为1024,需要将该值调高满足大并发网站的访问。 Linux每个用户打开文件最大数永久设置方法,将如下代码加入内核限制文件/etc/security/limits.conf的末尾,Exit退出终端,重新登录即生效:
* soft noproc 65535
* hard noproc 65535
* soft nofile 65535
* hard nofile 65535
5.3. Linux内核抛出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攻击类似。 完整的TCP连接的三次握手,假设一个用户A向服务器发送了SYN报文后突然死机或掉线,那么服务器在发出SYN+ACK应答报文后是无法收到客户端的ACK报文的(第三次握手无法完成),这种情况下服务器端一般会重试(再次发送SYN+ACK给客户端)并等待一段时间后丢弃这个未完成的连接,这段时间的长度我们称为SYN Timeout,一般来说这个时间是分钟的数量级(大约为30秒-2分钟)。 一个用户出现异常导致服务器的一个线程等待1分钟并不是什么很大的问题,但如果有一个恶意的攻击者大量模拟这种情况,服务器端将为了维护一个非常大的半连接列表而消耗非常多的资源,数以万计的半连接,即使是简单的保存并遍历也会消耗非常多的CPU时间和内存,何况还要不断对这个列表中的IP进行SYN+ACK的重试。 实际上如果服务器的TCP/IP栈不够强大,最后的结果往往是堆栈溢出崩溃,即使服务器端的系统足够强大,服务器端也将忙于处理攻击者伪造的TCP连接请求而无暇理睬客户的正常请求(毕竟客户端的正常请求比率非常之小),此时从正常客户的角度看来,服务器失去响应,服务器拒绝提供服务,服务器受到了DDOS攻击,这里攻击的手段为DDOS中SYN Flood攻击(SYN洪水攻击)。 防护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
5.4. Linux内核抛出ip_conntrack: table full, dropping packet.错误:
May 6 11 :15:07 localhost kernel: nf_conntrack:table full, dropping packet.
May 6 11 :19:13 localhost kernel: nf_conntrack:table full, dropping packet.
May 6 11 :20:34 localhost kernel: nf_conntrack:table full, dropping packet.
May 6 11 :23:12 localhost kernel: nf_conntrack:table full, dropping packet.
May 6 11 :24:07 localhost kernel: nf_conntrack:table full, dropping packet.
May 6 11 :24:13 localhost kernel: nf_conntrack:table full, dropping packet.
May 6 11 :25:11 localhost kernel: nf_conntrack:table full, dropping packet.
May 6 11 :26:25 localhost kernel: nf_conntrack:table full, dropping packet.
由于该服务器开启了iptables防火墙,WEB服务器收到了大量的连接,iptables会把所有的连接都做链接跟踪处理,这样iptables就会有一个链接跟踪表,当这个表满的时候,就会出现上面的错误。ip_conntrack是linux NAT的一个跟踪连接条目的模块,ip_conntrack模块会使用一个哈希表记录 tcp 通讯协议的established connection记录。 如果是CentOS6.x系统,需执行:modprobe nf_conntrack命令,然后在内核优化文件中(/etc/sysctl.conf)加入如下代码,sysctl –p使其内核文件生效,即可解决该报错:
net.nf_conntrack_max = 655360
net.netfilter.nf_conntrack_tcp_timeout_established = 36000
如果是CentOS5.x系统,需执行:modprobe ip_conntrack命令,然后在内核优化文件中加入如下代码,sysctl –p使其内核文件生效,即可解决该报错:
net.ipv4.ip_conntrack_max = 655350
net.ipv4.netfilter.ip_conntrack_tcp_timeout_established = 10800
6. 影响务器性能因素
影响企业生产环境Linux服务器性能的因素有很多,一般分为两大类,分别为操作系统层级和应用程序级别。如下为各级别影响性能的具体项及性能评估的标准:
操作系统级别
应用程序及软件
Linux系统性能评估标准如图所示:
6.1. Linux系统性能分析工具
vmstat、sar、iostat、netstat、free、ps、top、iftop等;
top、uptime 检查系统整体的负载、承受能力; vmstat、sar、iostat 、top 检测是否是CPU瓶颈; free、vmstat 检测是否是内存瓶颈; iostat 检测是否是磁盘I/O瓶颈; netstat、iftop 检测是否是网络带宽瓶颈。
7. Linux服务器性能评估与优化
Linux服务器性能评估与优化是一项长期的工作,需要随时关注网站服务器的运行状态,及时作出相应的调整,如下为Linux服务器性能评估及优化方案:
7.1. Linux系统整体性能评估
uptime命令主要用于查看当前服务器整体性能,例如CPU、负载、内存等值的总览,如下为uptime命令应用案例及详解:
[ root@web1 ~]
13 :38:00 up 112 days, 14 :01, 5 users, load average: 6.22 , 1.02 , 0.91
Load average负载有三个值,分别表示:最近1分钟、5分钟、15分钟系统的负载,三个值的大小一般不能大于系统逻辑CPU核数的2倍,例如Linux操作系统有4个逻辑CPU,如果load average的三个值长期大于8时,说明CPU很繁忙,负载很高,可能会影响系统性能,但是偶尔大于8时,可以不用担心,一般不会影响系统性能。 如果load average的输出值小于CPU逻辑个数的2倍,则表示CPU还有空闲的时间片,例如案例中CPU负载为6.22,表示CPU或者服务器是比较空闲的。基于此参数不能完全确认服务器的性能瓶颈,需要借助其他工具进一步判断。
7.2. CPU性能评估
利用vmstat命令监控系统CPU,该命令可以显示关于系统各种资源之间相关性能的简要信息,主要用它来查看CPU负载及队列情况。
[ root@manager ~]
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
1 0 0 1406844 2088 267504 0 0 2 0 71 116 0 0 100 0 0
0 0 0 1406828 2088 267536 0 0 0 0 129 219 0 0 100 0 0
0 0 0 1406828 2088 267536 0 0 0 0 122 211 0 0 100 0 0
0 0 0 1406828 2088 267536 0 0 0 0 123 206 0 0 100 0 0
0 0 0 1406828 2088 267536 0 0 0 0 127 225 0 0 100 0 0
0 0 0 1406432 2088 267536 0 0 0 0 165 268 0 0 100 0 0
2 0 0 1405896 2088 267536 0 0 0 1 139 236 0 0 100 0 0
0 0 0 1405896 2088 267536 0 0 0 0 121 213 0 0 100 0 0
2 0 0 1405864 2088 267536 0 0 0 2 131 217 0 0 100 0 0
0 0 0 1405864 2088 267536 0 0 0 0 136 241 0 0 100 0 0
r 列表示运行和等待cpu时间片的进程数,这个值如果长期大于系统CPU的个数,说明CPU不足,需要增加CPU b 列表示在等待资源的进程数,比如正在等待I/O、或者内存交换等 us 列显示了用户进程消耗的CPU 时间百分比。us的值比较高时,说明用户进程消耗的cpu时间多,但是如果长期大于50%,就需要考虑优化程序或算法; sy 列显示了内核进程消耗的CPU时间百分比。Sy的值较高时,说明内核消耗的CPU资源很多;
us+sy的参考值为80%,如果us+sy大于80%说明可能存在CPU资源不足。 利用sar命令监控系统CPU,sar功能很强大,可以对系统的每个方面进行单独的统计,但是使用sar命令会增加系统开销,不过这些开销是可以评估的,对系统的统计结果不会有很大影响。为sar命令对某个系统的CPU统计输出:
[ root@manager ~]
Linux 3.10 .0-1160.el7.x86_64 ( manager) 2023 年04月18日 _x86_64_ ( 2 CPU)
15 时08分33秒 CPU %user %nice %system %iowait %steal %idle
15 时08分35秒 all 0.00 0.00 0.25 0.00 0.00 99.75
15 时08分37秒 all 0.00 0.00 0.00 0.00 0.00 100.00
15 时08分39秒 all 0.25 0.00 0.25 0.00 0.00 99.50
15 时08分41秒 all 0.00 0.00 0.00 0.00 0.00 100.00
15 时08分43秒 all 0.00 0.00 0.25 0.00 0.00 99.75
15 时08分45秒 all 0.00 0.00 0.25 0.00 0.00 99.75
15 时08分47秒 all 0.00 0.00 0.00 0.00 0.00 100.00
15 时08分49秒 all 0.00 0.00 0.25 0.00 0.00 99.75
15 时08分51秒 all 0.25 0.00 0.00 0.00 0.00 99.75
15 时08分53秒 all 0.00 0.00 0.25 0.00 0.00 99.75
平均时间: all 0.05 0.00 0.15 0.00 0.00 99.80
%user 列显示了用户进程消耗的CPU 时间百分比 %nice 列显示了运行正常进程所消耗的CPU 时间百分比 %system 列显示了系统进程消耗的CPU时间百分比 %iowait 列显示了IO等待所占用的CPU时间百分比 %idle 列显示了CPU处在空闲状态的时间百分比 %steal 列显示了在内存相对紧张的环境下page in强制对不同的页面进行的steal操作
7.3. 内存性能评估
利用free指令监控内存,free是监控linux内存使用状况最常用的指令:
[ root@manager ~]
total used free shared buff/cache available
Mem: 1980 349 1180 9 450 1473
Swap: 0 0 0
一般而言,服务器内存可以通过如下方法判断是否空余:
应用程序可用内存/系统物理内存>70%时,表示系统内存资源非常充足,不影响系统性能。 应用程序可用内存/系统物理内存<20%时,表示系统内存资源紧缺,需要增加系统内存,20%<应用程序可用内存/系统物理内存<70%时,表示系统内存资源基本能满足应用需求,暂时不影响系统性能。
7.4. 磁盘I/O性能评估
利用iostat评估磁盘性能,监控磁盘IO读写及带宽
[ root@manager ~]
Linux 3.10 .0-1160.el7.x86_64 ( manager) 2023 年04月18日 _x86_64_ ( 2 CPU)
Device: tps kB_read/s kB_wrtn/s kB_read kB_wrtn
sda 0.20 5.27 0.67 435152 55670
scd0 0.00 0.01 0.00 1046 0
Device: tps kB_read/s kB_wrtn/s kB_read kB_wrtn
sda 0.00 0.00 0.00 0 0
scd0 0.00 0.00 0.00 0 0
Device: tps kB_read/s kB_wrtn/s kB_read kB_wrtn
sda 0.00 0.00 0.00 0 0
scd0 0.00 0.00 0.00 0 0
Device: tps kB_read/s kB_wrtn/s kB_read kB_wrtn
sda 0.00 0.00 0.00 0 0
scd0 0.00 0.00 0.00 0 0
Device: tps kB_read/s kB_wrtn/s kB_read kB_wrtn
sda 0.00 0.00 0.00 0 0
scd0 0.00 0.00 0.00 0 0
Device 磁盘设备名 tps 每秒钟传输的 I/O 请求次数 kB_read/s 每秒钟读取的数据量,以 KB/s 为单位 kB_wrtn/s 每秒钟写入的数据量,以 KB/s 为单位 kB_read 读取的总数据量,以 KB 为单位 kB_wrtn 写入的总数据量,以 KB 为单位
[ root@manager ~]
Linux 3.10 .0-1160.el7.x86_64 ( manager) 2023 年04月18日 _x86_64_ ( 2 CPU)
15 时46分11秒 DEV tps rd_sec/s wr_sec/s avgrq-sz avgqu-sz await svctm %util
15 时46分12秒 dev8-0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
15 时46分12秒 dev11-0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
15 时46分12秒 DEV tps rd_sec/s wr_sec/s avgrq-sz avgqu-sz await svctm %util
15 时46分13秒 dev8-0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
15 时46分13秒 dev11-0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
15 时46分13秒 DEV tps rd_sec/s wr_sec/s avgrq-sz avgqu-sz await svctm %util
15 时46分14秒 dev8-0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
15 时46分14秒 dev11-0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
15 时46分14秒 DEV tps rd_sec/s wr_sec/s avgrq-sz avgqu-sz await svctm %util
15 时46分15秒 dev8-0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
15 时46分15秒 dev11-0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
15 时46分15秒 DEV tps rd_sec/s wr_sec/s avgrq-sz avgqu-sz await svctm %util
15 时46分16秒 dev8-0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
15 时46分16秒 dev11-0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
平均时间: DEV tps rd_sec/s wr_sec/s avgrq-sz avgqu-sz await svctm %util
平均时间: dev8-0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
平均时间: dev11-0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
DEV 设备名 tps 每秒从物理磁盘I/O的次数,多个逻辑请求会被合并为一个I/O磁盘请求,一次传输的大小是不确定的 rd_sec/s 每秒读扇区的次数 wr_sec/s 每秒写扇区的次数 avgrq-sz 平均每次设备I/O操作的数据大小(扇区) avgqu-sz 磁盘请求队列的平均长度 await 从请求磁盘操作到系统完成处理,每次请求的平均消耗时间,包括请求队列等待时间,单位是毫秒(1秒=1000毫秒) svctm 系统处理每次请求的平均时间,不包括在请求队列中消耗的时间 %util I/O请求占CPU的百分比,比率越大,说明越饱和
1. avgqu-sz 的值较低时,设备的利用率较高。 2. %util I/O请求占用的CPU百分比,值越高,说明I/O越慢。
磁盘IO性能,评判标准:正常情况下svctm应该是小于await值的,而svctm的大小和磁盘性能有关,CPU、内存的负荷也会对svctm值造成影响,过多的请求也会间接的导致svctm值的增加。 await值的大小一般取决与svctm的值和I/O队列长度以及I/O请求模式,如果svctm的值与await很接近,表示几乎没有I/O等待,磁盘性能很好,如果await的值远高于svctm的值,则表示I/O队列等待太长,系统上运行的应用程序将变慢,此时可以通过更换更快的硬盘来解决问题。 %util项的值也是衡量磁盘I/O的一个重要指标,如果%util接近100%,表示磁盘产生的I/O请求太多,I/O系统已经满负荷的在工作,该磁盘可能存在瓶颈。长期下去,势必影响系统的性能,可以通过优化程序或者通过更换更高、更快的磁盘来解决此问题。