linux模拟资源占用 你会吗(你会.占用.模拟.资源.linux...........)

wufei123 2025-01-05 阅读:10 评论:0
公司拥有一批云服务器,这些服务器托管在华为云上,然而,很多云服务器的资源利用率并不高,处于空闲状态。我开始担心领导会察觉到这些空闲资源,要求我们降低配置,并可能削减云服务器的采购预算。因此,我计划编写一个 shell 脚本,用于模拟资源占用...

公司拥有一批云服务器,这些服务器托管在华为云上,然而,很多云服务器的资源利用率并不高,处于空闲状态。我开始担心领导会察觉到这些空闲资源,要求我们降低配置,并可能削减云服务器的采购预算。因此,我计划编写一个 shell 脚本,用于模拟资源占用的情况。

实施思路
  • 使用 stress 工具对内存进行压力测试,占用剩余内存的80%,以模拟CPU和内存的消耗情况。
  • 使用 dd 命令生成大文件,占用第二块硬盘剩余空间的80%,以模拟硬盘空间的消耗和IO操作。
  • 让脚本运行持续20分钟,一旦检测到内存占用超过80%,则停止压力测试。
  • 避免对CPU进行压力测试,因为过高的CPU占用率可能导致应用异常或服务器重启的风险。

相关工具

stress

stress 命令主要用来模拟系统负载较高时的场景,本文介绍其基本用法。文中 demo 的演示环境为 ubuntu 18.04。

可选参数

-c, –cpu N 产生 N 个进程,每个进程都反复不停的计算随机数的平方根

-i, –io N 产生 N 个进程,每个进程反复调用 sync() 将内存上的内容写到硬盘上

-m, –vm N 产生 N 个进程,每个进程不断分配和释放内存 –vm-bytes B 指定分配内存的大小

–vm-stride B 不断的给部分内存赋值,让 COW(Copy On Write)发生 –vm-hang N 指示每个消耗内存的进程在分配到内存后转入睡眠状态 N 秒,然后释放内存,一直重复执行这个过程

–vm-keep 一直占用内存,区别于不断的释放和重新分配(默认是不断释放并重新分配内存)

-d, –hadd N 产生 N 个不断执行 write 和 unlink 函数的进程(创建文件,写入内容,删除文件)

–hadd-bytes B 指定文件大小

-t, –timeout N 在 N 秒后结束程序 –backoff N 等待N微妙后开始运行

-q, –quiet 程序在运行的过程中不输出信息

-n, –dry-run 输出程序会做什么而并不实际执行相关的操作

–version 显示版本号

-v, –verbose 显示详细的信息

消耗 CPU 资源

stress 消耗 CPU 资源是通过调用 sqrt 函数计算由 rand 函数产生的随机数的平方根实现。下面的命令会产生 4 个这样的进程不断计算:

$ stress -c 

使用 top 命令查看 CPU 的状态如下(CPU 在用户态满负荷运转):

消耗内存资源

下面的命令产生两个子进程,每个进程分配 300M 内存:

$ stress --vm 2 --vm-bytes 300M --vm-keep

父进程处于睡眠状态,两个子进程负责资源消耗。

–vm-keep 一直占用内存,区别于不断的释放和重新分配(默认是不断释放并重新分配内存)。 –vm-hang N 指示每个消耗内存的进程在分配到内存后转入睡眠状态 N 秒,然后释放内存,一直重复执行这个过程。

–vm-keep 和 –vm-hang 都可以用来模拟只有少量内存的机器,但是指定它们时 CPU 的使用情况是不一样的。

$stress --vm 2 --vm-bytes 500M --vm-keep

一直在进行默认的 stride 操作,user 非常高(cpu 在用户态忙碌)。

$ stress --vm 2 --vm-bytes 500M --vm-hang 5

上面这两种状态不断切换,但整体上看 CPU 的负载并不高。

–vm-stride B 不断的给部分内存赋值,让 COW(Copy On Write)发生。只要指定了内存相关的选项,这个操作就会执行,只是大小为默认的 4096。赋值内存的比例由参数决定:

for (i = 0; i

$ stress --vm 2 --vm-bytes 500M --vm-stride 64
$ stress --vm 2 --vm-bytes 500M --vm-stride 1M

为什么会产生这样的结果?原因是单独的赋值和对比操作可以让 CPU 在用户态的负载占到 99% 以上。–vm-stride 值增大就意味着减少赋值和对比操作,这样就增加了内存的释放和分配次数(cpu在内核空间的负载)。 不指定 –vm-stride 选项就使用默认值是 4096,CPU 负载情况居于前两者之间:

$ stress --vm 2 --vm-bytes 500M

消耗 IO 资源 下面的命令产生 4 个进程,每个进程都反复调用 sync 函数将内存上的内容写到硬盘上:

$ stress -i 4

使用 top 命令查看 CPU 的状态如下:

sy 升高,wa(iowait) 非常高。

压测磁盘及 IO 下面的命令创建一个进程不断的在磁盘上创建 10M 大小的文件并写入内容:

$ stress -d 1 --hdd-bytes 10M

使用 top 命令查看 CPU 的状态如下(此时的 CPU 主要消耗在内核态):

下面是 iostat 2 的输出(同样是高 iowait,瓶颈是写磁盘):

其它选项

–verbose 显示 stress 程序运行过程中的详细信息:

–timeout N 在 N 秒后结束程序。

–quiet stress 程序运行的过程中不输出信息。

-n, –dry-run 输出程序会做什么而并不实际执行相关的操作:

–backoff N 让新 fork 出来的进程 sleep N 微秒再开始运行。

除了单独指定某一类的选项,还可以同时执行多个类型的任务,比如产生 3 个 CPU 进程、3 个 IO 进程、2 个10M 的 vm 进程,并且每个 vm 进程中不循环分配释放内存:

$ stress --cpu 3 --io 3 --vm 2 --vm-bytes 10M --vm-keep

dd

dd 命令 用于复制文件并对原文件的内容进行转换和格式化处理。dd 命令功能很强大的,对于一些比较底层的问题,使用 dd 命令往往可以得到出人意料的效果。用的比较多的还是用 dd 来备份裸设备。但是不推荐,如果需要备份 oracle 裸设备,可以使用 rman 备份,或使用第三方软件备份,使用 dd 的话,管理起来不太方便。需要的时候使用 dd 对物理磁盘操作,如果是文件系统的话还是使用 tar backup cpio 等其他命令更加方便。另外,使用 dd 对磁盘操作时,最好使用块设备文件。

语法
dd (选项)

命令选项
bs=:将ibs(输入)与obs(输出)设成指定的字节数;
cbs=:转换时,每次只转换指定的字节数;
conv=:指定文件转换的方式;
count=:仅读取指定的区块数;
ibs=:每次读取的字节数;
obs=:每次输出的字节数;
of=:输出到文件;
seek=:一开始输出时,跳过指定的区块数;
skip=:一开始读取时,跳过指定的区块数;
--help:帮助;
--version:显示版本信息。

实例
> dd if=/dev/zero of=sun.txt bs=1M count=1
1+0 records in
1+0 records out
1048576 bytes (1.0 MB) copied, 0.006107 seconds, 172 MB/s

[root@localhost text]
1.1M    sun.txt

该命令创建了一个 1M 大小的文件 sun.txt,其中参数解释:

  • if 代表输入文件。如果不指定 if,默认就会从 stdin 中读取输入。
  • of 代表输出文件。如果不指定 of,默认就会将 stdout 作为默认输出。
  • bs 代表字节为单位的块大小。
  • count 代表被复制的块数。
  • /dev/zero 是一个字符设备,会不断返回 0 值字节()。

块大小可以使用的计量单位表

单元大小 代码 字节(1B) c 字节(2B) w 块(512B) b 千字节(1024B) k 兆字节(1024KB) M 吉字节(1024MB) G

以上命令可以看出 dd 命令来测试内存操作速度:

> 1048576 bytes (1.0 MB) copied, 0.006107 seconds, 172 MB/s

生成随机字符串

我们甚至可以使用 /dev/urandom 设备配合 dd 命令 来获取随机字符串

> dd if=/dev/urandom bs=1 count=15|base64 -w 0
15+0 records in
15+0 records out
15 bytes (15 B) copied, 0.000111993 s, 134 kB/s
wFRAnlkXeBXmWs1MyGEs

常用案例汇总
1.将本地的/dev/hdb整盘备份到/dev/hdd
#dd if=/dev/hdb of=/dev/hdd
2.将/dev/hdb全盘数据备份到指定路径的image文件
#dd if=/dev/hdb of=/root/image
3.将备份文件恢复到指定盘
#dd if=/root/image of=/dev/hdb
4.备份/dev/hdb全盘数据,并利用gzip工具进行压缩,保存到指定路径
#dd if=/dev/hdb | gzip > /root/image.gz
5.将压缩的备份文件恢复到指定盘
#gzip -dc /root/image.gz | dd of=/dev/hdb
6.备份与恢复MBR
备份磁盘开始的512个字节大小的MBR信息到指定文件:
#dd if=/dev/hda of=/root/image count=1 bs=512
   count=1指仅拷贝一个块;bs=512指块大小为512个字节。
恢复:
#dd if=/root/image of=/dev/had
将备份的MBR信息写到磁盘开始部分
7.备份软盘
#dd if=/dev/fd0 of=disk.img count=1 bs=1440k (即块大小为1.44M)
8.拷贝内存内容到硬盘
#dd if=/dev/mem of=/root/mem.bin bs=1024 (指定块大小为1k)  
9.拷贝光盘内容到指定文件夹,并保存为cd.iso文件
#dd if=/dev/cdrom(hdc) of=/root/cd.iso
10.增加swap分区文件大小
第一步:创建一个大小为256M的文件:
#dd if=/dev/zero of=/swapfile bs=1024 count=262144
第二步:把这个文件变成swap文件:
#mkswap /swapfile
第三步:启用这个swap文件:
#swapon /swapfile
第四步:编辑/etc/fstab文件,使在每次开机时自动加载swap文件:
/swapfile    swap    swap    default   0 0
11.销毁磁盘数据
#dd if=/dev/urandom of=/dev/hda1
注意:利用随机的数据填充硬盘,在某些必要的场合可以用来销毁数据。
12.测试硬盘的读写速度
#dd if=/dev/zero bs=1024 count=1000000 of=/root/1Gb.file
#dd if=/root/1Gb.file bs=64k | dd of=/dev/null
通过以上两个命令输出的命令执行时间,可以计算出硬盘的读、写速度。
13.确定硬盘的最佳块大小:
#dd if=/dev/zero bs=1024 count=1000000 of=/root/1Gb.file
#dd if=/dev/zero bs=2048 count=500000 of=/root/1Gb.file
#dd if=/dev/zero bs=4096 count=250000 of=/root/1Gb.file
#dd if=/dev/zero bs=8192 count=125000 of=/root/1Gb.file
通过比较以上命令输出中所显示的命令执行时间,即可确定系统最佳的块大小。
14.修复硬盘:
#dd if=/dev/sda of=/dev/sda 或dd if=/dev/hda of=/dev/hda
当硬盘较长时间(一年以上)放置不使用后,磁盘上会产生magnetic flux point,当磁头读到这些区域时会遇到困难,并可能导致I/O错误。当这种情况影响到硬盘的第一个扇区时,可能导致硬盘报废。上边的命令有可能使这些数 据起死回生。并且这个过程是安全、高效的。
15.利用netcat远程备份
#dd if=/dev/hda bs=16065b | netcat  1234
在源主机上执行此命令备份/dev/hda
#netcat -l -p 1234 | dd of=/dev/hdc bs=16065b
在目的主机上执行此命令来接收数据并写入/dev/hdc
#netcat -l -p 1234 | bzip2 > partition.img
#netcat -l -p 1234 | gzip > partition.img
以上两条指令是目的主机指令的变化分别采用bzip2、gzip对数据进行压缩,并将备份文件保存在当前目录。
将一个很大的视频文件中的第i个字节的值改成0x41(也就是大写字母A的ASCII值)
echo A | dd of=bigfile seek=$i bs=1 count=1 conv=notrunc

脚本

编写的shell脚本如下:

#!/bin/bash
#模拟cpu,IO,内存使用
#ver 1.0
#每天凌晨1:00执行
#持续20分钟

#记录执行日志
script_log="script_log.log"
mem_info=$(free -m | grep Mem)
used_mem=$(echo $mem_info | awk '{print $3}')
total_mem=$(echo $mem_info | awk '{print $2}')
# 计算内存利用率
mem_util=$(echo "scale=2; $used_mem / $total_mem * 100" | bc)
#内存利用率取整数
mem_utilization=$(printf "%.0f" "$mem_util")

if [ ! -f "$script_log" ]; then
  touch "$script_log"
fi


# 模拟内存占用
function simulate_memory() {

  #安装stress压测工具
  INSTALLED=$(rpm -qa | grep stress)
  if [ $? -eq 0 ];then
    echo "$(date +%Y-%m-%d-%H:%M) 已经安装了stress" >> $script_log
  else
    yum install stress -y
    sleep 5
  fi
  #执行内存
  if [ $mem_utilization -lt 80 ];then
    stress --io 1 --vm 1 --vm-bytes "$(awk '/MemFree/{printf "%d
", 0.7*$2}' /proc/meminfo)k" --vm-keep &
    echo "$(date +%Y-%m-%d-%H:%M) 执行内存压测命令 " >> $script_log
  fi

}

#模拟file占用
function simulate_file() {
  #判断第二硬盘是否存在
  second_disk=$(lsblk | grep -w "vd[b-z]")
  if [ $? -eq 0 ];then
    echo "$(date +%Y-%m-%d-%H:%M) 第二块硬盘存在" >> $script_log
    if [ -d "/data" ];then
      if [ -d "/data/second_disk_data_tmp" ];then
        echo "$(date +%Y-%m-%d-%H:%M) 临时目录/data/second_disk_data_tmp已存在" >> $script_log
      else
        mkdir -p /data/second_disk_data_tmp
        echo "$(date +%Y-%m-%d-%H:%M) 临时目录/data/second_disk_data_tmp不存在,已创建" >> $script_log
      fi
    fi
  else
    echo "$(date +%Y-%m-%d-%H:%M) 第二块硬盘不存在" >> $script_log
  fi
  #执行前先删除临时文件

  if [ -f "/data/second_disk_data_tmp/data_tmp.txt" ];then
    rm -f /data/second_disk_data_tmp/data_tmp.txt
    echo "$(date +%Y-%m-%d-%H:%M) /data/second_disk_data_tmp/data_tmp.txt 文件存在,已删除"
  else 
    touch /data/second_disk_data_tmp/data_tmp.txt
  fi

  #第二块盘磁盘利用率
  second_disk_usage=$(df -h | egrep  "vd[b-z]" | awk '{ print $5 }' | tr -d "%")
  #需要占用的磁盘空间大小
  file_size=$(df -h | egrep  "vd[b-z]" | awk '{ print $4*0.8 }' | tr -d "G"|bc)
  #去整数
  size_file=$(printf "%.0f" "$file_size")
  #计算需要生成的文件大小
  #如果第二盘的空间小于80
  if [ $second_disk_usage -lt 80 ];then 
  #dd命令生成文件
    time1=$(date +%s)
    echo "$(date +%Y-%m-%d-%H:%M) 开始执行生成临时文件" >> $script_log
    dd if=/dev/zero  of=/data/second_disk_data_tmp/data_tmp.txt bs=1G count=$size_file
    time2=$(date +%s)
    time3=$((time2-time1))
    echo "$(date +%Y-%m-%d-%H:%M) 生成了临时文件,路径为/data/second_disk_data_tmp/data_tmp.txt,花费时间$time3 秒" >> $script_log
    if  [ $second_disk_usage -ge 80 ];then 
      if [ -f "/data/second_disk_data_tmp/data_tmp.txt" ];then
        rm -rf /data/second_disk_data_tmp/data_tmp.txt
        echo "$(date +%Y-%m-%d-%H:%M) 第二盘硬盘利用率大于80%,已删除临时文件" >> $script_log
      fi
    fi
  fi
}
start_time=$(date +%s)
simulate_memory
simulate_file
start_time=$(date +%s)
#此刻的内存利用率

while true;do
  #计算此时内存利用率
  mem_info_now=$(free -m | grep Mem)
  used_mem_now=$(echo $mem_info_now | awk '{print $3}')
  total_mem_now=$(echo $mem_info_now | awk '{print $2}')
  # 计算内存利用率
  mem_util_now=$(echo "scale=2; $used_mem_now / $total_mem_now * 100" | bc)
  mem_utilization_now=$(printf "%.0f" "$mem_util_now")
  current_time=$(date +%s)
  elapsed_time=$((current_time - start_time))

  if [ $mem_utilization_now -ge 80 ];then
     for i in $(ps aux | grep "stress --io" | awk '{ print $2}');do kill -9 $i;done
     echo "$(date +%Y-%m-%d-%H:%M) 内存利用率大于80%停止stress命令 " >> $script_log
     sleep 10
     simulate_memory
     sleep 10
  fi
  if [ $elapsed_time -ge 1200 ]; then
    break
  fi
  sleep 10
done
for i in $(ps aux | grep "stress --io" | awk '{ print $2}');do kill -9 $i;done
echo "$(date +%Y-%m-%d-%H:%M) 结束内存压测" >> $script_log
end_time=$(date +%s)
cost_time=$((end_time - start_time))
echo "$(date +%Y-%m-%d-%H:%M) 程序已经运行:$cost_time 秒 并结束" >> $script_log
exit 0

执行效果

cpu

linux模拟资源占用 你会吗

内存

linux模拟资源占用 你会吗

IO

linux模拟资源占用 你会吗

相关问题

1 dd命令执行时间过长,持续将近十几分钟

2 dd执行过程中磁盘IO基本上被占满

以上就是linux模拟资源占用 你会吗的详细内容,更多请关注知识资源分享宝库其它相关文章!

版权声明

本站内容来源于互联网搬运,
仅限用于小范围内传播学习,请在下载后24小时内删除,
如果有侵权内容、不妥之处,请第一时间联系我们删除。敬请谅解!
E-mail:dpw1001@163.com

分享:

扫一扫在手机阅读、分享本文

发表评论
热门文章
  • 华为 Mate 70 性能重回第一梯队 iPhone 16 最后一块遮羞布被掀

    华为 Mate 70 性能重回第一梯队 iPhone 16 最后一块遮羞布被掀
    华为 mate 70 或将首发麒麟新款处理器,并将此前有博主爆料其性能跑分将突破110万,这意味着 mate 70 性能将重新夺回第一梯队。也因此,苹果 iphone 16 唯一能有一战之力的性能,也要被 mate 70 拉近不少了。 据悉,华为 Mate 70 性能会大幅提升,并且销量相比 Mate 60 预计增长40% - 50%,且备货充足。如果 iPhone 16 发售日期与 Mate 70 重合,销量很可能被瞬间抢购。 不过,iPhone 16 还有一个阵地暂时难...
  • 酷凛 ID-COOLING 推出霜界 240/360 一体水冷散热器,239/279 元

    酷凛 ID-COOLING 推出霜界 240/360 一体水冷散热器,239/279 元
    本站 5 月 16 日消息,酷凛 id-cooling 近日推出霜界 240/360 一体式水冷散热器,采用黑色无光低调设计,分别定价 239/279 元。 本站整理霜界 240/360 散热器规格如下: 酷凛宣称这两款水冷散热器搭载“自研新 V7 水泵”,采用三相六极马达和改进的铜底方案,缩短了水流路径,相较上代水泵进一步提升解热能力。 霜界 240/360 散热器的水泵为定速 2800 RPM 设计,噪声 28db (A)。 两款一体式水冷散热器采用 27mm 厚冷排,...
  • 惠普新款战 99 笔记本 5 月 20 日开售:酷睿 Ultra / 锐龙 8040,4999 元起

    惠普新款战 99 笔记本 5 月 20 日开售:酷睿 Ultra / 锐龙 8040,4999 元起
    本站 5 月 14 日消息,继上线官网后,新款惠普战 99 商用笔记本现已上架,搭载酷睿 ultra / 锐龙 8040处理器,最高可选英伟达rtx 3000 ada 独立显卡,售价 4999 元起。 战 99 锐龙版 R7-8845HS / 16GB / 1TB:4999 元 R7-8845HS / 32GB / 1TB:5299 元 R7-8845HS / RTX 4050 / 32GB / 1TB:7299 元 R7 Pro-8845HS / RTX 2000 Ada...
  • python中def什么意思

    python中def什么意思
    python 中,def 关键字用于定义函数,这些函数是代码块,执行特定任务。函数语法为 def (参数列表)。函数可以通过其名字和圆括号调用。函数可以接受参数作为输入,并在函数体中使用参数名访问。函数可以使用 return 语句返回一个值,它将成为函数调用的结果。 Python 中 def 关键字 在 Python 中,def 关键字用于定义函数。函数是代码块,旨在执行特定任务。 语法 def 函数定义的语法如下: def (参数列表): # 函数体 示例 定义...
  • python中int函数的用法

    python中int函数的用法
    int() 函数将值转换为整数,支持多种类型(字符串、字节、浮点数),默认进制为 10。可以指定进制数范围在 2-36。int() 返回 int 类型的转换结果,丢弃小数点。例如,将字符串 "42" 转换为整数为 42,将浮点数 3.14 转换为整数为 3。 Python 中的 int() 函数 int() 函数用于将各种类型的值转换为整数。它接受任何可以解释为整数的值作为输入,包括字符串、字节、浮点数和十六进制表示。 用法 int(object, base=10) 其中...