该命令能用于拉升单个cpu使用率
cat /dev/zero>/dev/null
执行yum -y install sysstat
命令安装工具, mpstat -P ALL 1 10
命令查看负载情况
mpstat -P ALL 1 10
CPU %usr %nice %sys %iowait %irq %soft ... %idle
all 17.57 0.03 1.78 0.00 0.35 0.23 ... 80.04
0 43.17 0.00 4.12 0.00 1.41 1.00 ... 50.30
1 9.80 0.00 0.81 0.00 0.00 0.00 ... 89.39
2 9.31 0.00 1.20 0.00 0.00 0.00 ... 89.49
3 7.94 0.10 0.80 0.00 0.00 0.00 ... 91.16
如上命令的含义是每秒运行一次 mpstat,一共采样 10 次取平均值,可以明显看出 CPU0
的空闲 idle 明显小于其它 CPUx,而且大部分都消耗在了用户态 usr 上面。各参数含义可以对照下面表格1
mpstat 命令参数 | 解释 |
---|---|
-P | 表示监控哪个CPU,例如mpstat -P 0、mpstat -P 7、mpstat -P ALL、mpstat -P 0,2 |
-A | 等同于-u -I ALL -P ALL |
-I | 可以指定SUM、CPU、SCPU、ALL四个参数,SUM表示每个处理器的中断总数,CPU表示每个核的每秒中断数量, SCPU表示每个核每秒的软中断数量,内核版本在2.6.31之后才支持 |
internal | 相邻的两次采样的间隔时间 |
count | 采样的次数,count只能和delay一起使用 |
当没有参数时,mpstat只显示系统所有信息的平均值,有internal参数时,第一行的信息是自系统启动以来的平均信息,从第二行开始,输出为前一个internal时间段的平均信息 |
mpstat 返回值 | 解释 | 从/proc/stat获得数据 |
---|---|---|
%usr | 用户态下,cpu的利用率 | usr/total*100 |
%nice | 具有nice优先级的用户下,CPU的使用率 | nice/total*100 |
%sys | 显示在kernel内核态执行时发生的CPU利用率百分比。这不包括维护硬件和软件中断所花费的时间 | system/total*100 |
%iowait | 显示系统有未完成的磁盘I/O请求时,CPU或CPU处于空闲状态的时间百分比 | iowait/total*100 |
%irq | 系统服务于硬中断的时间开销的百分比 | irq/total*100 |
%soft | 系统服务于软中断开销的时间开销百分比 | softirq/total*100 |
%steal | 显示虚拟CPU或CPU在虚拟机监控程序为另一个虚拟处理器提供服务时被迫等待所花费的时间百分比 | steal/total*100 |
%guest | CPU处理虚拟进程的花费的时间开销 | guest/total*100 |
%gnice | gnice/total*100 | |
%idle | CPU空闲百分比 | idle/total*100 |
继续通过 pidstat
命令来确认一下是不是 PHP-FPM
导致的CPU0
负载问题 , 第一列是出现次数,第二列表示第几个CPU2
pidstat | grep php-fpm | awk '{print $(NF-1)}' | sort | uniq -c
157 0
34 1
34 2
32 3
可见分配给 CPU0 的 PHP-FPM 进程比其他三个 CPUx 总和还要多, 大部分进程被分配给了 CPU0
,可能是操作系统偏爱使用 CPU0, 针对这个问题, PHP-FPM
及时没有类似 Nginx 那样 CPU 亲缘性(affinity)绑定的指令,我们仍然可以使用 taskset 绑定 PHP-FPM 进程到固定的 CPUx 来解决问题:
#!/bin/bash
CPUs=$(grep -c processor /proc/cpuinfo)
PIDs=$(ps aux | grep "php-fpm[:] pool" | awk '{print $2}')
let i=0
for PID in $PIDs; do
CPU=$(echo "$i % $CPUs" | bc)
let i++
taskset -pc $CPU $PID
done
执行脚本后各个 CPU 负载分配变得较为平均
mpstat -P ALL 1 10
CPU %usr %nice %sys %iowait %irq %soft ... %idle
all 15.73 0.03 1.61 0.00 0.20 0.23 ... 82.20
0 16.28 0.10 1.62 0.10 0.81 0.91 ... 80.18
1 16.16 0.10 1.51 0.00 0.00 0.10 ... 82.13
2 14.46 0.10 1.71 0.00 0.00 0.00 ... 83.73
3 15.95 0.00 1.71 0.00 0.00 0.00 ... 82.35
需要注意的是,一旦 PHP-FPM 处理的请求数超过 max_requests 的设置,那么对应的进程将自动重启,先前的taskset
设置也将失效,所以为了一直有效,我们需要把 taskset 脚本添加定时任务中自动执行
top
或者htop
命令查看 CPU 使用情况 3%Cpu(s): 0.3 us, 0.1 sy, 0.0 ni, 99.6 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
参数 | 解释 |
---|---|
us(user) | 表示 CPU 在用户运行的时间百分比,通常用户 CPU 高表示有应用程序比较繁忙。典型的用户程序有数据库、Web 服务器等。 |
sy(sys) | 表示 CPU 在内核态运行的时间百分比(不包括中断),通常内核态 CPU 越低越好,否则表示系统存在某些瓶颈。 |
ni(nice) | 表示用 nice 修正进程优先级的用户进程执行的 CPU 时间。nice 是一个进程优先级的修正值,如果进程通过它修改了优先级,则会单独统计 CPU 开销。 |
id(idle) | 表示 CPU 处于空闲态的时间占比,此时,CPU 会执行一个特定的虚拟进程,名为 System Idle Process。 |
wa(iowait) | 表示 CPU 在等待 I/O 操作完成所花费的时间,通常该指标越低越好,否则表示 I/O 存在瓶颈,可以用 iostat 等命令做进一步分析。 |
hi(hardirq) | 表示 CPU 处理硬中断所花费的时间。硬中断是由外设硬件(如键盘控制器、硬件传感器等)发出的,需要有中断控制器参与,特点是快速执行。 |
si(softirq) | 表示 CPU 处理软中断所花费的时间。软中断是由软件程序(如网络收发、定时调度等)发出的中断信号,特点是延迟执行。 |
st(steal) | 表示 CPU 被其他虚拟机占用的时间,仅出现在多虚拟机场景。如果该指标过高,可以检查下宿主机或其他虚拟机是否异常。 |
top -Hp
命令找到 CPU 消耗最多的线程号(列名仍然为 PID)# (3) 通过printf "%x\n" <线程号>
命令输出该线程号对应的 16 进制数字
jstack <进程号> | grep <16进制线程号> -A 10
命令找到 CPU 消耗最多的线程方法堆栈。perf
, 没有该命令的话可以执行yum install perf -y
安装perf top -p 7574
perf利用Linux的trace特性,可以用于实时跟踪,统计event计数(perf stat);或者使用采样(perf record),报告(perf report|script|annotate)的使用方式进行诊断。可以通过CPUQuota
参数来设置4, 例如 systemctl set-property foo.service CPUQuota=200%
#!/bin/bash
# auth:kaliarch
# func:sys info check
# version:v1.0
# sys:centos6.x/7.x
set -e
[ $(id -u) -gt 0 ] && exit 1
# cpu使用超过百分之多少进行限制
PEC_CPU=80
# 限制进程使用百分之多少,如果程序为多线程,单个cpu限制为85,如果为多核心,就需要按照比例写,例如cpu为2c,像限制多线程占比80%,就写170
LIMIT_CPU=85
# 日志
LOG_DIR=/var/log/cpulimit/
# 超过阀值进程pid
PIDARG=$(ps -aux |awk -v CPU=${PEC_CPU} '{if($3 > CPU) print $2}')
CPULIMITCMD=$(which cpulimit)
install_cpulimit() {
[ ! -d /tmp ] && mkdir /tmp || cd /tmp
wget -c https://github.com/opsengine/cpulimit/archive/v0.2.tar.gz
tar -zxf v0.2.tar.gz
cd cpulimit-0.2 && make
[ $? -eq 0 ] && cp src/cpulimit /usr/bin/
}
do_cpulimit() {
[ ! -d ${LOG_DIR} ] && mkdir -p ${LOG_DIR}
for i in ${PIDARG};
do
MSG=$(ps -aux |awk -v pid=$i '{if($2 == pid) print $0}')
echo ${MSG}
[ ! -d /tmp ] && mkdir /tmp || cd /tmp
nohup ${CPULIMITCMD} -p $i -l ${LIMIT_CPU} &
echo "$(date) -- ${MSG}" >> ${LOG_DIR}$(date +%F).log
done
}
main() {
hash cpulimit
if [ $? -eq 0 ];then
do_cpulimit
else
install_cpulimit && do_cpulimit
fi
}
main
#!/bin/env python
import math
import random
a=10000
b=10000
c=10000
sum=0
for i in range(0,a):
for j in range(0,b):
randomfloat=random.uniform(1,10)
randompow=random.uniform(1,10)
sum+=math.pow(randomfloat, randompow)
print "sum is %s" % sum
将 cpulimit.sh 设置成crontab定时任务后再运行测试脚本就能看到cpu限制效果
查看系统负载的工具:uptime
,w
,都能查看系统负载,系统平均负载是处于运行或不可打扰状态的进程的平均数6,
使用uptime查看系统负载
# uptime
10:10:22 up 55 days, 22:13, 1 user, load average: 0.00, 0.01, 0.05
这里我们关注的是最后三列,即系统1分钟、5分钟、15分钟内的平均负载,判断一个系统负载是否偏高需要计算单核CPU的平均负载,等于这里uptime命令显示的系统平均负载 / CPU核数,一般以0.7为比较合适的值。偏高说明有比较多的进程在等待使用CPU资源。
使用 w
命令也可以查看类似的信息,w
命令还提供了当前登录用户,以及正在执行的操作等信息。
系统负载可以是CPU密集型的,也可以是RAM密集型和I/O密集型的,CPU密集型的系统比I/O密集型的系统响应度更好,因为I/O密集型的系统的磁盘I/O可能完全饱和,导致登录就很费事。
https://www.csdn.net/tags/OtDaIg1sOTgxMjctYmxvZwO0O0OO0O0O.html ↩︎
https://cloud.tencent.com/developer/article/1918126?from=15425 ↩︎
https://cloud.tencent.com/developer/article/1876605?from=15425 ↩︎
https://zhuanlan.zhihu.com/p/75422252 ↩︎
https://cloud.tencent.com/developer/article/1363553?from=15425 ↩︎
https://www.lmlphp.com/user/76842/article/item/838561 ↩︎