Shell脚本查看linux系统性能瓶颈

简介: Shell脚本查看linux系统性能瓶颈

 linux服务器敲命令反应慢,网站访问慢,到底什么情况?根据本人的经验,主要原因可能是系统资源到达瓶颈,已经无法处理更多请求。在有监控系统情况下,可以直接通过WEB页面可视化看出是CPU瓶颈?硬盘瓶颈?还是网络瓶颈?如果公司服务器较少或者云服务器,就有可能没有一套监控系统,这时就要登陆到服务器,一条一条的敲命令,查找分析性能瓶颈。命令这么多,咋记得住啊!就算记得住,输入也费劲,于是就有了这个脚本,为了以后自己使用,另外也想分享给博友,学shell朋友能从中得到一丢丢启发。写的比较仓促,内容有点粗略,还望君见谅!

脚本目的:分析系统资源性能瓶颈

脚本功能:

1、查看CPU利用率与负载(top、vmstat、sar)

2、查看磁盘、Inode利用率与I/O负载(df、iostat、iotop、sar、dstat)

3、查看内存利用率(free、vmstat)

4、查看TCP连接状态(netstat、ss)

5、查看CPU与内存占用最高的10个进程(top、ps)

6、查看网络流量(ifconfig、iftop、iptraf)

脚本说明:通过一些常用的性能分析工具,计算出我们想知道的信息。

脚本如下:

# cat show_sys_info.sh

#!/bin/bash
#
os_check() {
        if [ -e /etc/redhat-release ]; then
                REDHAT=`cat /etc/redhat-release |cut -d' '  -f1`
        else
                DEBIAN=`cat /etc/issue |cut -d' ' -f1`
        fi
        if [ "$REDHAT" == "CentOS" -o "$REDHAT" == "Red" ]; then
                P_M=yum
        elif [ "$DEBIAN" == "Ubuntu" -o "$DEBIAN" == "ubutnu" ]; then
                P_M=apt-get
        else
                Operating system does not support.
                exit 1
        fi
}
if [ $LOGNAME != root ]; then
    echo "Please use the root account operation."
    exit 1
fi
if ! which vmstat &>/dev/null; then
        echo "vmstat command not found, now the install."
        sleep 1
        os_check
        $P_M install procps -y
        echo "-----------------------------------------------------------------------"
fi
if ! which iostat &>/dev/null; then
        echo "iostat command not found, now the install."
        sleep 1
        os_check
        $P_M install sysstat -y
        echo "-----------------------------------------------------------------------"
fi

while true; do
    select input in cpu_load disk_load disk_use disk_inode mem_use tcp_status cpu_top10 mem_top10 traffic quit; do
        case $input in
            cpu_load)
                #CPU利用率与负载
                echo "---------------------------------------"
                i=1
                while [[ $i -le 3 ]]; do
                    echo -e "\033[32m  参考值${i}\033[0m"
                    UTIL=`vmstat |awk '{if(NR==3)print 100-$15"%"}'`
                    USER=`vmstat |awk '{if(NR==3)print $13"%"}'`
                    SYS=`vmstat |awk '{if(NR==3)print $14"%"}'`
                    IOWAIT=`vmstat |awk '{if(NR==3)print $16"%"}'`
                    echo "Util: $UTIL"
                    echo "User use: $USER"
                    echo "System use: $SYS"
                    echo "I/O wait: $IOWAIT"
                    i=$(($i+1))
                    sleep 1
                done
                echo "---------------------------------------"
                break
                ;;
            disk_load)
                #硬盘I/O负载
                echo "---------------------------------------"
                i=1
                while [[ $i -le 3 ]]; do
                    echo -e "\033[32m  参考值${i}\033[0m"
                    UTIL=`iostat -x -k |awk '/^[v|s]/{OFS=": ";print $1,$NF"%"}'`
                    READ=`iostat -x -k |awk '/^[v|s]/{OFS=": ";print $1,$6"KB"}'`
                    WRITE=`iostat -x -k |awk '/^[v|s]/{OFS=": ";print $1,$7"KB"}'`
                    IOWAIT=`vmstat |awk '{if(NR==3)print $16"%"}'`
                    echo -e "Util:"
                    echo -e "${UTIL}"
                    echo -e "I/O Wait: $IOWAIT"
                    echo -e "Read/s:\n$READ"
                    echo -e "Write/s:\n$WRITE"
                    i=$(($i+1))
                    sleep 1
                done
                echo "---------------------------------------"
                break
                ;;
            disk_use)
                #硬盘利用率
                DISK_LOG=/tmp/disk_use.tmp
                DISK_TOTAL=`fdisk -l |awk '/^Disk.*bytes/&&/\/dev/{printf $2" ";printf "%d",$3;print "GB"}'`
                USE_RATE=`df -h |awk '/^\/dev/{print int($5)}'`
                for i in $USE_RATE; do
                    if [ $i -gt 90 ];then
                        PART=`df -h |awk '{if(int($5)=='''$i''') print $6}'`
                        echo "$PART = ${i}%" >> $DISK_LOG
                    fi
                done
                echo "---------------------------------------"
                echo -e "Disk total:\n${DISK_TOTAL}"
                if [ -f $DISK_LOG ]; then
                    echo "---------------------------------------"
                    cat $DISK_LOG
                    echo "---------------------------------------"
                    rm -f $DISK_LOG
                else
                    echo "---------------------------------------"
                    echo "Disk use rate no than 90% of the partition."
                    echo "---------------------------------------"
                fi
                break
                ;;
            disk_inode)
                #硬盘inode利用率
                INODE_LOG=/tmp/inode_use.tmp
                INODE_USE=`df -i |awk '/^\/dev/{print int($5)}'`
                for i in $INODE_USE; do
                    if [ $i -gt 90 ]; then
                        PART=`df -h |awk '{if(int($5)=='''$i''') print $6}'`
                        echo "$PART = ${i}%" >> $INODE_LOG
                    fi
                done
                if [ -f $INODE_LOG ]; then
                    echo "---------------------------------------"
                    rm -f $INODE_LOG
                else
                    echo "---------------------------------------"
                    echo "Inode use rate no than 90% of the partition."
                    echo "---------------------------------------"
                fi
                break
                ;;
            mem_use)
                #内存利用率
                echo "---------------------------------------"
                MEM_TOTAL=`free -m |awk '{if(NR==2)printf "%.1f",$2/1024}END{print "G"}'`
                USE=`free -m |awk '{if(NR==3) printf "%.1f",$3/1024}END{print "G"}'`
                FREE=`free -m |awk '{if(NR==3) printf "%.1f",$4/1024}END{print "G"}'`
                CACHE=`free -m |awk '{if(NR==2) printf "%.1f",($6+$7)/1024}END{print "G"}'`
                echo -e "Total: $MEM_TOTAL"
                echo -e "Use: $USE"
                echo -e "Free: $FREE"
                echo -e "Cache: $CACHE"
                echo "---------------------------------------"
                break
                ;;
            tcp_status)
                #网络连接状态
                echo "---------------------------------------"
                COUNT=`netstat -antp |awk '{status[$6]++}END{for(i in status) print i,status[i]}'`
                echo -e "TCP connection status:\n$COUNT"
                echo "---------------------------------------"
                ;;
            cpu_top10)
                #占用CPU高的前10个进程
                echo "---------------------------------------"
                CPU_LOG=/tmp/cpu_top.tmp
                i=1
                while [[ $i -le 3 ]]; do
                    #ps aux |awk '{if($3>0.1)print "CPU: "$3"% -->",$11,$12,$13,$14,$15,$16,"(PID:"$2")" |"sort -k2 -nr |head -n 10"}' > $CPU_LOG
                    ps aux |awk '{if($3>0.1){{printf "PID: "$2" CPU: "$3"% --> "}for(i=11;i<=NF;i++)if(i==NF)printf $i"\n";else printf $i}}' |sort -k4 -nr |head -10 > $CPU_LOG
                    #循环从11列(进程名)开始打印,如果i等于最后一行,就打印i的列并换行,否则就打印i的列
                    if [[ -n `cat $CPU_LOG` ]]; then
                       echo -e "\033[32m  参考值${i}\033[0m"
                       cat $CPU_LOG
                       > $CPU_LOG
                    else
                        echo "No process using the CPU." 
                        break
                    fi
                    i=$(($i+1))
                    sleep 1
                done
                echo "---------------------------------------"
                break
                ;;
            mem_top10)
                #占用内存高的前10个进程
                echo "---------------------------------------"
                MEM_LOG=/tmp/mem_top.tmp
                i=1
                while [[ $i -le 3 ]]; do
                    #ps aux |awk '{if($4>0.1)print "Memory: "$4"% -->",$11,$12,$13,$14,$15,$16,"(PID:"$2")" |"sort -k2 -nr |head -n 10"}' > $MEM_LOG
                    ps aux |awk '{if($4>0.1){{printf "PID: "$2" Memory: "$3"% --> "}for(i=11;i<=NF;i++)if(i==NF)printf $i"\n";else printf $i}}' |sort -k4 -nr |head -10 > $MEM_LOG
                    if [[ -n `cat $MEM_LOG` ]]; then
                        echo -e "\033[32m  参考值${i}\033[0m"
                        cat $MEM_LOG
                        > $MEM_LOG
                    else
                        echo "No process using the Memory."
                        break
                    fi
                    i=$(($i+1))
                    sleep 1
                done
                echo "---------------------------------------"
                break
                ;;
            traffic)
                #查看网络流量
                while true; do
                    read -p "Please enter the network card name(eth[0-9] or em[0-9]): " eth
                    #if [[ $eth =~ ^eth[0-9]$ ]] || [[ $eth =~ ^em[0-9]$ ]] && [[ `ifconfig |grep -c "\<$eth\>"` -eq 1 ]]; then
                    if [ `ifconfig |grep -c "\<$eth\>"` -eq 1 ]; then
                            break
                    else
                        echo "Input format error or Don't have the card name, please input again."
                    fi
                done
                echo "---------------------------------------"
                echo -e " In ------ Out"
                i=1
                while [[ $i -le 3 ]]; do
                    #OLD_IN=`ifconfig $eth |awk '/RX bytes/{print $2}' |cut -d: -f2`
                    #OLD_OUT=`ifconfig $eth |awk '/RX bytes/{print $6}' |cut -d: -f2`
                    OLD_IN=`ifconfig $eth |awk -F'[: ]+' '/bytes/{if(NR==8)print $4;else if(NR==5)print $6}'`
                    #CentOS6和CentOS7 ifconfig输出进出流量信息位置不同,CentOS6中RX与TX行号等于8,CentOS7中RX行号是5,TX行号是5,所以就做了个判断.       
                    OLD_OUT=`ifconfig $eth |awk -F'[: ]+' '/bytes/{if(NR==8)print $9;else if(NR==7)print $6}'`
                    sleep 1
                    NEW_IN=`ifconfig $eth |awk -F'[: ]+' '/bytes/{if(NR==8)print $4;else if(NR==5)print $6}'`
                    NEW_OUT=`ifconfig $eth |awk -F'[: ]+' '/bytes/{if(NR==8)print $9;else if(NR==7)print $6}'`
                    IN=`awk 'BEGIN{printf "%.1f\n",'$((${NEW_IN}-${OLD_IN}))'/1024/128}'`
                    OUT=`awk 'BEGIN{printf "%.1f\n",'$((${NEW_OUT}-${OLD_OUT}))'/1024/128}'`
                    echo "${IN}MB/s ${OUT}MB/s"
                    i=$(($i+1))
                    sleep 1
                done
                echo "---------------------------------------"
                break
                ;;
                        quit)
                                exit 0
                                ;;
               *)
                    echo "---------------------------------------"
                    echo "Please enter the number." 
                    echo "---------------------------------------"
                    break
                    ;;
        esac
    done
done

注意:在原来基础上增加了退出选项,同时也更新了一些小bug,以下图片没有显示。

运行效果如下:

# sh show_sys_info.sh

wKiom1XaurSDzLBXAAMdO4UDpdI025.jpg

wKioL1XavNDz2ColAAKfiL9gQcY036.jpg

wKiom1XausWyO2gVAAFAY7EdoqI526.jpg


wKioL1XavOLSOWyMAAC8Xbwvrnc180.jpg


wKiom1XautjQWnVRAAD4ZKO60co516.jpg

wKiom1XauuGijj0hAAFHNT4ntPY686.jpg



wKioL1XavP_w4aoRAAKkhcqRrjA796.jpg

wKiom1XauvSTS6AXAAYZcjwUE-I338.jpg

wKioL1XavRPRRn_lAAEmDF96Tqk993.jpg


相关文章
|
1月前
|
Linux
Linux系统之whereis命令的基本使用
Linux系统之whereis命令的基本使用
83 24
Linux系统之whereis命令的基本使用
|
11天前
|
存储 缓存 Linux
Linux系统中如何查看CPU信息
本文介绍了查看CPU核心信息的方法,包括使用`lscpu`命令和读取`/proc/cpuinfo`文件。`lscpu`能快速提供逻辑CPU数量、物理核心数、插槽数等基本信息;而`/proc/cpuinfo`则包含更详细的配置数据,如核心ID和处理器编号。此外,还介绍了如何通过`lscpu`和`dmidecode`命令获取CPU型号、制造商及序列号,并解释了CPU频率与缓存大小的相关信息。最后,详细解析了`lscpu`命令输出的各项参数含义,帮助用户更好地理解CPU的具体配置。
45 8
|
11天前
|
关系型数据库 Shell 网络安全
定期备份数据库:基于 Shell 脚本的自动化方案
本篇文章分享一个简单的 Shell 脚本,用于定期备份 MySQL 数据库,并自动将备份传输到远程服务器,帮助防止数据丢失。
|
1月前
|
Shell Linux
【linux】Shell脚本中basename和dirname的详细用法教程
本文详细介绍了Linux Shell脚本中?`basename`和?`dirname`命令的用法,包括去除路径信息、去除后缀、批量处理文件名和路径等。同时,通过文件备份和日志文件分离的实践应用,展示了这两个命令在实际脚本中的应用场景。希望本文能帮助您更好地理解和应用?`basename`和?`dirname`命令,提高Shell脚本编写的效率和灵活性。
107 32
|
11天前
|
存储 运维 监控
深度体验便宜云服务器系统控制台:SysOM 让 Linux 服务器监控变得如此简单
作为一名经历过无数个凌晨三点被服务器报警电话惊醒的运维工程师,我对监控工具有着近乎苛刻的要求。记得去年那次大型活动,我们的主站流量暴增,服务器内存莫名其妙地飙升到90%以上,却找不到原因。如果当时有一款像便宜云服务器 SysOM 这样直观的监控工具,也许我就不用熬通宵排查问题了。今天,我想分享一下我使用 SysOM 的亲身体验,特别是它那令人印象深刻的内存诊断功能。
|
1月前
|
存储 Linux 网络安全
linux应急响应检查脚本
通过这个脚本,可以快速收集系统的关键信息,有助于在发生问题时进行及时的应急响应和分析。
111 34
|
21天前
|
JavaScript Shell C#
多种脚本批量下载 Docker 镜像:Shell、PowerShell、Node.js 和 C#
本项目提供多种脚本(Shell、PowerShell、Node.js 和 C#)用于批量下载 Docker 镜像。配置文件 `docker-images.txt` 列出需要下载的镜像及其标签。各脚本首先检查 Docker 是否安装,接着读取配置文件并逐行处理,跳过空行和注释行,提取镜像名称和标签,调用 `docker pull` 命令下载镜像,并输出下载结果。使用时需创建配置文件并运行相应脚本。C# 版本需安装 .NET 8 runtime。
104 2
|
2月前
|
缓存 安全 Linux
Linux系统查看操作系统版本信息、CPU信息、模块信息
在Linux系统中,常用命令可帮助用户查看操作系统版本、CPU信息和模块信息
179 23
|
Unix Shell Linux
|
7月前
|
Shell Linux 程序员
在Linux中, 什么是shell函数?如何使用它们?
在Linux中, 什么是shell函数?如何使用它们?
http://www.vxiaotou.com