混沌工程之注入内存耗尽(控制内存使用率为100%)

同CPU使用率一样,内存使用率也是希望越低越好,但混沌工程需要注入内存耗尽的故障,我们今天研究下如何控制内存使用率持续100%。

混沌工程中为什么注入内存耗尽故障呢?系统中当然不期望内存耗尽,但期望内存耗尽后系统能否自动恢复,自动恢复的时长。

借用阿里混沌工程实践,内存耗尽如下:系统层-系统异常-内存耗尽。

阿里混沌工程测试模板
脚本chaos-mem-001.sh

实现思想:借鉴虚拟内存的思想,创建虚拟内存文件系统,不断写入数据达到消耗内存的目的,需要清除内存时,删除创建的虚拟内存目录即可。

#!/bin/bash 

#使用虚拟内存构造内存消耗

mkdir /tmp/memory 

#tmpfs是一种虚拟内存文件系统,而不是块设备(tmpfs不具备持久性)。是基于内存的文件系统,创建时不需要使用mkfs等初始化,最大的特点是它的存储空间在VM(virtual memory),VM是由linux内核里面的vm子系统管理的。linux下面VM的大小由RM(Real Memory)和swap组成,RM的大小就是物理内存的大小,而Swap的大小是由自己决定的。Swap是通过硬盘虚拟出来的内存空间,因此它的读写速度相对RM(Real Memory)要慢许多,当一个进程申请一定数量的内存时,如内核的vm子系统发现没有足够的RM时,就会把RM里面的一些不常用的数据交换到Swap里面。VM由RM+Swap两部分组成,因此tmpfs最大的存储空间可达(The size of RM + The  size of Swap)。 但是对于tmpfs本身而言,它并不知道自己使用的空间是RM还是Swap,这一切都是由内核的vm子系统管理的。tmpfs默认的大小是RM的一半Tmpfs大小调整:/etc/fstab中看到tmpfs类型的挂载点中找到待修改的,先umount tmpfs(操作前先备份),在/etc/fstab修改挂载点的容量后再mount tmpfs。脚本中挂载一个待注入内存大小的内存系统

mount -t tmpfs -o size=300M tmpfs /tmp/memory 

dd if=/dev/zero of=/tmp/memory/block 

sleep 3600s

#释放消耗的虚拟内存

rm /tmp/memory/block 

umount /tmp/memory 

rmdir /tmp/memory 


脚本chaos-mem-002.sh:原理同001,易用性更好

#!/bin/bash

#      mem used script

#      eg. ./mem.sh 60G & to start testing

#      eg. ./mem.sh stop  to stop testing and clear env

#      update: 2019-1-22  pansaky


num=$1

user=`whoami`

start()

{

      if [ -d /tmp/memory ];then

              echo "the dir "/tmp/memory" is already exist!, use it." >> mem.log

      else

              sudo mkdir /tmp/memory

              mount -t tmpfs -o size=$num tmpfs /tmp/memory

      fi

      dd if=/dev/zero of=/tmp/memory/block >> mem.log 2>&1

}

stop()

{

      rm -rf /tmp/memory/block

      umount /tmp/memory

      rmdir /tmp/memory

      if [ -d /tmp/memory ];then

              echo "Do not remove the dir \"/tmp/memory\", please check "

      else

            echo "clear env is done!"

      fi

}

main()

{

    if [ $num == 'stop' ];then

              stop

    elif [ $user != "root" ];then

            echo "please use the \"root\" excute script!"

              exit 1

      else

              start

      fi

}

if [ $# = 2 -o $# = 1 ];then

        main

else

        echo 'Usage: <./mem.sh 60G &> to start  or <./mem.sh stop>  to clear env'

fi

C语言脚本chaos-mem-003

/*usage: gcc mem.c -o mem.out 编译出Linux下可执行的文件,使用./mem.out 100 & 消耗对应数字MB单位的内存,释放时杀掉对应进程即可,如果是内存耗尽,该进程会被操作系统oom杀掉*/

#include

#include

#include

#define UNIT (1024*1024)

# argc是外部输入的参数个数,argv[ ]是参数的字符串数组。

int main(int argc, char *argv[])

{

        long long i = 0;

        int size = 0;

        if (argc != 2) {

                printf(" === argc must 2\n");

                return 1;

        }

        # strtoul函数:strtoul() 函数源自于“string to unsigned long”,用来将字符串转换成无符号长整型数(unsigned long)。strtol() 函数用来将字符串转换为长整型数(long)。

      size = strtoul(argv[1], NULL, 10);

        if (size == 0) {

                printf(" argv[1]=%s not good\n", argv[1]);

                return 1;

        }

# malloc向系统申请分配指定size个字节的内存空间。返回类型是 void* 类型。void* 表示未确定类型的指针。C,C++规定,void* 类型可以强制转换为任何其它类型的指针。malloc及其相关函数calloc,free,realloc,brk在表头文件#include

        char *buff = (char *) malloc(size * UNIT);

        if (buff)

                printf(" we malloced %d Mb\n", size);

        buff[0] = 1;

        for (i = 1; i < (size * UNIT); i++) {

                if (i%1024 == 0)

                        buff[i] = buff[i-1]/8;

                else

                        buff[i] = i/2;

        }

        pause();

}

C语言脚本chaos-mem-004

#include

#include

using namespace std;

void main()

{

          int i=0;

          double *a=NULL;

          while(true)

            {

            # 申请8k字节的空间(1000个double类型值,double类型为8个字节),并且把a指向该空间所在位置

            a=(double*) malloc (sizeof(double) *1000);

              # 在VC中Sleep()的单位是毫秒,如果函数滞留1秒的话,应该是Sleep(1000);在Linux下sleep()的单位是秒。

                Sleep(1);

            }

}

参考

Linux内存测试---构造消耗内存shell脚本

linux内存测试(占用)脚本

你可能感兴趣的:(混沌工程之注入内存耗尽(控制内存使用率为100%))