Linux性能优化实战

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 Number32位确认序列号包含发送确认的一端所期望收到的下一个序号,因此,确认序号应当是上次已成功收到数据字节序号Seq加1。不过,只有当标志位中的ACK标志(下面介绍)为1时该确认序列号的字段才有效。主要用来解决不丢包的问题;ACK= seq + 1
Offset给出首部中32 bit字的数目,需要这个值是因为任选字段的长度是可变的。这个字段占4bit(最多能表示15个32bit的的字,即4*15=60个字节的首部长度),因此TCP最多有60字节的首部。然而,没有任选字段,正常的长度是20字节
TCP FlagsTCP首部中有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文件打开最大数

  • 为了防止失控的进程破坏系统的性能,Unix和Linux会跟踪进程使用的大部分资源,并允许用户和系统管理员使用对进程的资源限制,例如控制某个进程打开的系统文件数、对某个用户打开系统进程数进行限制等,一般限制手段包括:软限制和硬限制。
  • 软限制(soft limit)是内核实际执行的限制,任何进程都可以将软限制设置为任意小于等于对进程限制的硬限制的值,(noproc)最大线程数和(nofile)文件数;
  • 硬限制(hard limit)是可以在任何时候任何进程中设置,但硬限制只能由超级用户修改。
  • Linux系统一切皆文件,对Linux进行各种操作,其实是对文件进行操作,文件可分为:普通文件、目录文件、链接文件和设备文件。而文件描述符(file descriptor)是Linux系统为了高效管理已被打开的文件所创建的索引,其值一个非负整数(通常是小整数),用于指代被打开的文件,所有执行I/O操作的系统调用都通过文件描述符。
  • Linux系统默认已经打开的文件描述符包括:STDIN_FILENO 0表示标准输入、STDOUT_FILENO 1表示标准输出、STDERR_FILENO 2表示标准错误输出,默认打开一个新文件,它的文件描述符为3。
  • 每个文件描述符与一个打开文件相对应,不同的文件描述符可以指向同一个文件。相同的文件可以被不同的进程打开,也可以在同一个进程中被多次打开。
  • Linux系统为每个进程维护了一个文件描述符表,该表的值都从0开始的,在不同的进程中你会看到相同的文件描述符,相同文件描述符有可能指向同一个文件,也有可能指向不同的文件。Linux内核对文件操作,维护了3个数据结构概念如下:
  1. 进程级的文件描述符表;
  2. 系统级的打开文件描述符表;
  3. 文件系统的i-node表;
  • 其中进程级的描述符表的每一个条目记录了单个文件描述符的相关信息,例如控制文件描述符操作的一组标志及对打开文件句柄的引用。Linux内核对所有打开的文件都维护了一个系统级的描述符表(open file description table)。将描述符表中的记录行称为打开文件句柄(open file handle),一个打开文件句柄存储了与一个打开文件相关的全部信息,详细信息如下:
  1. 当前文件偏移量
  2. 打开文件时所使用的状态标识
  3. 文件访问模式
  4. 与信号驱动相关的设置
  5. 对该文件i-node对象的引用
  6. 文件类型和访问权限
  7. 指针,指向该文件所持有的锁列表
  8. 文件的各种属性
  • 默认Linux内核对每个用户设置了打开文件最大数为1024,对于高并发网站,是远远不够的,需要将默认值调整到更大,调整方法有两种:
  • Linux每个用户打开文件最大数临时设置方法,重启服务器该参数无效,命令行终端执行如下命令:
[root@node1 ~]# ulimit   -SHn  65535
[root@node1 ~]# ulimit -n
65535
  • inux每个用户打开文件最大数永久设置方法,将如下代码加入内核限制文件/etc/security/limits.conf的末尾:
[root@node1 ~]# vim /etc/security/limits.conf
在末尾添加下面内容
* 	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 = 5tcp_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 = 1TCP建立连接的 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 356736net.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服务器性能的因素有很多,一般分为两大类,分别为操作系统层级和应用程序级别。如下为各级别影响性能的具体项及性能评估的标准:
  1. 操作系统级别
  • 内存;
  • CPU;
  • 磁盘I/O;
  • 网络I/O带宽;
  • Linux内核参数;
  1. 应用程序及软件
  • Nginx;
  • Mysql;
  • Tomcat;
  • PHP;
  • Redis;
  • Zabbix;
  • Jenkins;
  • ELK;
  • 应用程序代码;
  • 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 ~]# uptime
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 ~]# vmstat  2 10
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
  • Vmstat输出结果详解如下:
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 ~]# sar -u 2 10
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
  • Sar输出结果详解如下:
%user列显示了用户进程消耗的CPU 时间百分比
%nice列显示了运行正常进程所消耗的CPU 时间百分比
%system列显示了系统进程消耗的CPU时间百分比
%iowait列显示了IO等待所占用的CPU时间百分比
%idle列显示了CPU处在空闲状态的时间百分比
%steal列显示了在内存相对紧张的环境下page in强制对不同的页面进行的steal操作

7.3. 内存性能评估

  • 利用free指令监控内存,free是监控linux内存使用状况最常用的指令:
[root@manager ~]# free -m
              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 ~]# iostat -d  1 5
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

  • iostat输出结果详解如下:
Device磁盘设备名
tps每秒钟传输的 I/O 请求次数
kB_read/s每秒钟读取的数据量,以 KB/s 为单位
kB_wrtn/s每秒钟写入的数据量,以 KB/s 为单位
kB_read读取的总数据量,以 KB 为单位
kB_wrtn写入的总数据量,以 KB 为单位
  • 可以通过kB_read/s和kB_wrtn/s的值对磁盘的读写性能有一个基本的了解,如果Blk_wrtn/s值很大,表示磁盘的写操作很频繁,可以考虑优化磁盘或者优化程序,如果Blk_read/s值很大,表示磁盘直接读取操作很多,可以将读取的数据放入内存中进行操作。

  • 利用sar评估磁盘性能,通过sar -d组合,可以对系统的磁盘IO做一个基本的统计

[root@manager ~]# sar -d 1 5
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
  • Sar输出结果详解如下:
DEV设备名
tps每秒从物理磁盘I/O的次数,多个逻辑请求会被合并为一个I/O磁盘请求,一次传输的大小是不确定的
rd_sec/s每秒读扇区的次数
wr_sec/s每秒写扇区的次数
avgrq-sz平均每次设备I/O操作的数据大小(扇区)
avgqu-sz磁盘请求队列的平均长度
await从请求磁盘操作到系统完成处理,每次请求的平均消耗时间,包括请求队列等待时间,单位是毫秒(1秒=1000毫秒)
svctm系统处理每次请求的平均时间,不包括在请求队列中消耗的时间
%utilI/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系统已经满负荷的在工作,该磁盘可能存在瓶颈。长期下去,势必影响系统的性能,可以通过优化程序或者通过更换更高、更快的磁盘来解决此问题。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值