Linux常用命令总结及错误排查分析

拉升CPU使用率

该命令能用于拉升单个cpu使用率

cat /dev/zero>/dev/null

查看多核CPU负载情况及设置负载分配

执行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
%guestCPU处理虚拟进程的花费的时间开销guest/total*100
%gnicegnice/total*100
%idleCPU空闲百分比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 脚本添加定时任务中自动执行


CPU使用率过高的排查方法


使用 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 被其他虚拟机占用的时间,仅出现在多虚拟机场景。如果该指标过高,可以检查下宿主机或其他虚拟机是否异常。

(1) 通过 top 命令找到 CPU 消耗最多的进程号

在这里插入图片描述

(2) 通过 top -Hp <PID>命令找到 CPU 消耗最多的线程号(列名仍然为 PID)

在这里插入图片描述# (3) 通过printf "%x\n" <线程号>命令输出该线程号对应的 16 进制数字

在这里插入图片描述

(4) 查看PID进程在内核调用情况

  • 如果是Java应用可通过jstack <进程号> | grep <16进制线程号> -A 10命令找到 CPU 消耗最多的线程方法堆栈。
  • 非 Java 应用可使用 perf , 没有该命令的话可以执行yum install perf -y 安装
    perf top -p 7574
    
    在这里插入图片描述perf利用Linux的trace特性,可以用于实时跟踪,统计event计数(perf stat);或者使用采样(perf record),报告(perf report|script|annotate)的使用方式进行诊断。

让一个 cgroup 完全使用两个 CPU 核

可以通过CPUQuota参数来设置4, 例如 systemctl set-property foo.service CPUQuota=200%

Linux系统进程CPU使用率限制脚本

  • cpulimit.sh5 CPU使用率限制脚本如下:
    #!/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
    
  • 用python测试脚本来将CPU跑满
    #!/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限制效果

其他命令查看CPU负载

查看系统负载的工具:uptimew ,都能查看系统负载,系统平均负载是处于运行或不可打扰状态的进程的平均数6

  • 可运行:运行态,占用CPU,或就绪态,等待CPU调度。
  • 不可打扰:阻塞,正在等待I/O

使用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可能完全饱和,导致登录就很费事。

参考


  1. https://www.csdn.net/tags/OtDaIg1sOTgxMjctYmxvZwO0O0OO0O0O.html ↩︎

  2. https://cloud.tencent.com/developer/article/1918126?from=15425 ↩︎

  3. https://cloud.tencent.com/developer/article/1876605?from=15425 ↩︎

  4. https://zhuanlan.zhihu.com/p/75422252 ↩︎

  5. https://cloud.tencent.com/developer/article/1363553?from=15425 ↩︎

  6. https://www.lmlphp.com/user/76842/article/item/838561 ↩︎

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值