Linux性能优化学习笔记
1.什么是平均负载?
uptime命令
[root@b0b5a9371ce4 /]# uptime
09:59:49 up 11 days, 14:50, 0 users, load average: 0.16, 0.07, 0.02
09:59:49 //当前时间
up 11 days, 14:50 //系统运行时间
0 user //正在登录用户数
//load average 依次则是过去 1 分钟、5 分钟、15 分钟的平均负载
load average: 0.16, 0.07, 0.02
平均负载是指单位时间内,系统处于可运行状态和不可中断状态的平均进程数,也就是平均活跃进程数,它和 CPU 使用率并没有直接关系。
2.查看Cpu上下文切换?
vmstat 5
参数解释:
- cs(context switch)是每秒上下文切换的次数。
- in(interrupt)则是每秒中断的次数。
- r(Running or Runnable)是就绪队列的长度,也就是正在运行和等待 CPU 的进程数。
- b(Blocked)则是处于不可中断睡眠状态的进程数。
要想查看每个进程的详细情况,就需要使用我们前面提到过的 pidstat 了。给它加上 -w 选项,你就可以查看每个进程上下文切换的情况了。
pidstat -w 5 // 没隔5秒输出一组数据
3.CPU使用率很高,但找不到应用?
pstree 就可以用树状形式显示所有进程之间的关系:
# pstree -apnh //显示进程间的关系
它可以用来分析 CPU 性能事件,用在这里就很合适。依旧在第一个终端中运行 perf record -g 命令 ,并等待一会儿(比如 15 秒)后按 Ctrl+C 退出。然后再运行 perf report 查看报告:
# 记录性能事件,等待大约15秒后按 Ctrl+C 退出
$ perf record -g
# 查看报告
$ perf report
用 execsnoop 监控上述案例,就可以直接得到 stress 进程的父进程 PID 以及它的命令行参数,并可以发现大量的 stress 进程在不停启动:
execsnoop 所用的 ftrace 是一种常用的动态追踪技术,一般用于分析 Linux 内核的运行时行为,后面课程我也会详细介绍并带你使用。
4.系统中大量僵尸进程和不可用进程,怎么办?
进程状态,使用ps aux
或 top -c
查看:
[push@cp-pre Log]$ ps aux | grep Swoole
push 9783 0.0 0.0 112828 980 pts/1 S+ 10:25 0:00 grep --color=auto Swoole
work 13303 0.8 0.9 630268 78060 ? Sl 08:23 1:02 EasySwoole.TaskWorker.2
work 14816 0.8 0.9 1269480 72984 ? Sl 08:29 1:00 EasySwoole.TaskWorker.1
work 15659 0.8 0.9 1322792 74372 ? Sl 08:32 0:58 EasySwoole.TaskWorker.0
work 19629 0.8 0.8 1433160 70596 ? Sl 08:49 0:49 EasySwoole.TaskWorker.3
work 26367 1.2 0.7 1219700 59412 ? Ssl 3月11 12:24 EasySwoole
work 26368 0.0 0.3 492740 25000 ? S 3月11 0:00 EasySwoole
work 26372 0.7 0.6 590724 49600 ? Sl 3月11 7:14 EasySwoole.Worker.0
work 26373 0.7 0.6 615132 48104 ? Sl 3月11 7:19 EasySwoole.Worker.1
work 26374 0.7 0.6 593148 50568 ? Sl 3月11 7:14 EasySwoole.Worker.2
work 26375 0.7 0.6 591100 49444 ? Sl 3月11 7:17 EasySwoole.Worker.3
work 26376 0.7 0.6 593116 49728 ? Sl 3月11 7:16 EasySwoole.Worker.4
work 26377 0.7 0.6 601700 48700 ? Sl 3月11 7:12 EasySwoole.Worker.5
work 26378 0.7 0.6 591128 49316 ? Sl 3月11 7:17 EasySwoole.Worker.6
work 26379 0.7 0.6 612000 48740 ? Sl 3月11 7:18 EasySwoole.Worker.7
work 26380 0.0 0.3 496888 26372 ? S 3月11 0:44 EasySwoole
work 26381 0.0 0.3 496888 27228 ? S 3月11 0:04 EasySwoole.Crontab
work 26386 0.0 0.3 498936 25600 ? S 3月11 0:03 EasySwoole.Bridge
- R 是 Running 或 Runnable 的缩写,表示进程在 CPU 的就绪队列中,正在运行或者正在等待运行。D 是 Disk Sleep 的缩写,也就是不可中断状态睡眠(Uninterruptible Sleep),一般表示进程正在跟硬件交互,并且交互过程不允许被其他进程或中断打断。
- Z 是 Zombie 的缩写,如果你玩过“植物大战僵尸”这款游戏,应该知道它的意思。它表示僵尸进程,也就是进程实际上已经结束了,但是父进程还没有回收它的资源(比如进程的描述符、PID 等)。
- S 是 Interruptible Sleep 的缩写,也就是可中断状态睡眠,表示进程因为等待某个事件而被系统挂起。当进程等待的事件发生时,它会被唤醒并进入 R 状态。
- I 是 Idle 的缩写,也就是空闲状态,用在不可中断睡眠的内核线程上。前面说了,硬件交互导致的不可中断进程用
- D 表示,但对某些内核线程来说,它们有可能实际上并没有任何负载,用 Idle 正是为了区分这种情况。要注意,D 状态的进程会导致平均负载升高, I 状态的进程却不会。
会话和进程组:s 表示这个进程是一个会话的领导进程,而 + 表示前台进程组。
- 进程组表示一组相互关联的进程,比如每个子进程都是父进程所在组的成员;
- 而会话是指共享同一个控制终端的一个或多个进程组。
用我们最熟悉的 ps 或者 top ,可以查看进程的状态,这些状态包括运行(R)、空闲(I)、不可中断睡眠(D)、可中断睡眠(S)、僵尸(Z)以及暂停(T)等
解决步骤 :
1.我们在终端中运行 dstat 命令,观察 CPU 和 I/O 的使用情况:
dstat 1 10
使用 pidstat,但这次去掉进程号,干脆就来观察所有进程的 I/O 使用情况。
# 间隔 1 秒输出多组数据 (这里是 20 组)
$ pidstat -d 1 20
5.Cpu性能优化的几个思路?
以 Web 应用为例:
- 应用程序的维度,我们可以用吞吐量和请求延迟来评估应用程序的性能。
- 系统资源的维度,我们可以用 CPU 使用率来评估系统的 CPU 使用情况。
6.linux内存是怎么工作的?
++内存映射:++ Linux 内核给每个进程都提供了一个独立的虚拟地址空间,并且这个地址空间是连续的。这样,进程就可以很方便地访问内存,更确切地说是访问虚拟内存。
内存映射,其实就是将虚拟内存地址映射到物理内存地址。为了完成内存映射,内核为每个进程都维护了一张页表,记录虚拟地址与物理地址的映射关系。
++虚拟内存空间分布++:
1.只读段,包括代码和常量等。
2.数据段,包括全局变量等。
3.堆,包括动态分配的内存,从低地址开始向上增长。
4.文件映射段,包括动态库、共享内存等,从高地址开始向下增长。
5.栈,包括局部变量和函数调用的上下文等。栈的大小是固定的,一般是 8 MB。
在这五个内存段中,堆和文件映射段的内存是动态分配的。比如说,使用 C 标准库的 malloc() 或者 mmap() ,就可以分别在堆和文件映射段动态分配内存。
如何查看内存使用情况:
free
- 第一列,total 是总内存大小;
- 第二列,used 是已使用内存的大小,包含了共享内存;
- 第三列,free 是未使用内存的大小;
- 第四列,shared 是共享内存的大小;
- 第五列,buff/cache 是缓存和缓冲区的大小;
- 最后一列,available 是新进程可用内存的大小。
++Buffer 和 Cache++:Buffer 是对磁盘数据的缓存,而 Cache 是文件数据的缓存,它们既会用在读请求中,也会用在写请求中。
内存回收 栈内存由系统自动分配和管理。一旦程序运行超出了这个局部变量的作用域,栈内存就会被系统自动回收,所以不会产生内存泄漏的问题。堆内存由应用程序自己来分配和管理。
7.linux 缓存命中率
所谓缓存命中率,是指直接通过缓存获取数据的请求次数,占所有数据请求次数的百分比。
cachestat 和 cachetop ,它们正是查看系统缓存命中情况的工具。(需手动安装工具包)
8.linux文件结构
Linux 文件系统为每个文件都分配两个数据结构,索引节点(index node) 和目录项 (directory entry)
- 索引节点,简称为 inode,用来记录文件的元数据,比如 inode 编号、文件大小、访问权限、修改日期、数据的位置等。索引节点和文件一一对应,它跟文件内容一样,都会被持久化存储到磁盘中。所以记住,索引节点同样占用磁盘空间。
- 目录项,简称为 dentry,用来记录文件的名字、索引节点指针以及与其他目录项的关联关系。多个关联的目录项,就构成了文件系统的目录结构。不过,不同于索引节点,目录项是由内核维护的一个内存数据结构,所以通常也被叫做目录项缓存。
目录项、索引节点、逻辑块以及超级块,构成了 Linux 文件系统的四大基本要素。
VFS 内部又通过目录项、索引节点、逻辑块以及超级块等数据结构,来管理文件。
- 目录项,记录了文件的名字,以及文件与其他目录项之间的目录关系。
- 索引节点,记录了文件的元数据。
- 逻辑块,是由连续磁盘扇区构成的最小读写单元,用来存储文件数据。
- 超级块,用来记录文件系统整体的状态,如索引节点和逻辑块的使用情况等。
其中,目录项是一个内存缓存;而超级块、索引节点和逻辑块,都是存储在磁盘中的持久化数据。
容量查看:
df -hi
9.linux磁盘I/O是怎么工作的?
磁盘性能的衡量标准,必须要提到五个常见指标,也就是我们经常用到的,使用率、饱和度、IOPS、吞吐量以及响应时间等。这五个指标,是衡量磁盘性能的基本指标。
- 使用率,是指磁盘处理 I/O 的时间百分比。过高的使用率(比如超过 80%),通常意味着磁盘 I/O 存在性能瓶颈。
- 饱和度,是指磁盘处理 I/O 的繁忙程度。过高的饱和度,意味着磁盘存在严重的性能瓶颈。当饱和度为 100% 时,磁盘无法接受新的 I/O 请求。
- IOPS(Input/Output Per Second),是指每秒的 I/O 请求数。
- 吞吐量,是指每秒的 I/O 请求大小。
- 响应时间,是指 I/O 请求从发出到收到响应的间隔时间。
10.查看套接字信息
套接字信息:
# head -n 3 表示只显示前面3行
# -l 表示只显示监听套接字
# -n 表示显示数字地址和端口(而不是名字)
# -p 表示显示进程信息
$ netstat -nlp | head -n 3
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 127.0.0.53:53 0.0.0.0:* LISTEN 840/systemd-resolve
# -l 表示只显示监听套接字
# -t 表示只显示 TCP 套接字
# -n 表示显示数字地址和端口(而不是名字)
# -p 表示显示进程信息
$ ss -ltnp | head -n 3
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 127.0.0.53%lo:53 0.0.0.0:* users:(("systemd-resolve",pid=840,fd=13))
LISTEN 0 128 0.0.0.0:22 0.0.0.0:* users:(("sshd",pid=1459,fd=3))
由于低层协议是高层协议的基础,所以一般情况下,我们所说的网络优化,实际上包含了整个网络协议栈的所有层的优化。
11.使用tcpdump/Wireshark分析网络流量?
tcpdump 和 Wireshark 就是最常用的网络抓包和分析工具,更是分析网络性能必不可少的利器。
12.实践篇
查看被系统OOM命令:
dmesg
链路层定位网络丢包:
netstat -i
输出中的 RX-OK、RX-ERR、RX-DRP、RX-OVR ,分别表示接收时的总包数、总错误数、进入 Ring Buffer 后因其他原因(如内存不足)导致的丢包数以及 Ring Buffer 溢出导致的丢包数。
TX-OK、TX-ERR、TX-DRP、TX-OVR 也代表类似的含义,只不过是指发送时对应的各个指标。
网络层和传输层定位丢包:
netstat -s
主要观察IpExt的数据。
iptables 规则,统一管理在一系列的表中,包括 filter(用于过滤)、nat(用于 NAT)、mangle(用于修改分组数据) 和 raw(用于原始数据包)等。而每张表又可以包括一系列的链,用于对 iptables 规则进行分组管理。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战