监控云磁盘IOPS(次/s)的测试方法

2021-05-14  本文已影响0人  程序员馨馨紫

一、项目背景

需要实时监控云服务器上实例的云盘IOPS(次/s),类似于腾讯云和阿里云的监控数据

二、开发实现思路

通过Prometheus监控系统,按一定的规则采集OpenStack宿主机上各虚拟机的数据,保存在时序库中,再按照产品需求,按照一定的算法,将数据展示在对应页面上

三、测试环境准备

A、Linux服务器一台
1、在Linux服务器上搭建一个ftp服务器(可用phpstudy工具,正在研究中,后续分享)
2、在Linux机器上安装nmon,可参考:https://www.jianshu.com/p/f3282733d245
3、在本地windows机器上安装工具FlashFXP,可上传下载文件产生带宽,流量,IO和网络

四、测试方法--Linux系统

云盘IOPS(次/s),包括硬盘读次数(即硬盘平均每秒读次数)和写次数(即硬盘平均每秒写次数)

1、测试硬盘读次数:

A、用工具FlashFXP工具连接到开启了ftp服务的目录例如:/data2,对应磁盘sdb,不同磁盘对应的目录不一样


8.png

B、测试硬盘读次数,即从服务器下载文件,且限制速度为1024KB/秒(限速的目的是为了使数据稳定,便于测试)


9.png
10.png
C、在nmon中导出.nmon文件数据,硬盘读次数对应DISKXFER中的数据(单位为次数或个)
13.png

D、对比测试数据
截图为腾讯云的数据,仅供参考


14.png
2、测试硬盘写次数:

A、用工具FlashFXP工具连接到开启了ftp服务的目录例如:/data2,对应磁盘sdb,不同磁盘对应的目录不一样


8.png

B、测试硬盘写次数,即上传文件至服务器,且限制速度为1024KB/秒(限速的目的是为了使数据稳定,便于测试)


9.png
10.png
C、在nmon中导出.nmon文件数据,硬盘写次数对应DISKXFER中的数据(单位为次数或个)
13.png

D、对比测试数据
截图为腾讯云的数据,仅供参考


23.png

五、测试方法--Windows系统

云盘IOPS(次/s),包括硬盘读次数(即硬盘平均每秒读次数)和写次数(即硬盘平均每秒写次数)

1、测试硬盘读次数:

A、用工具FlashFXP工具连接到开启了ftp服务的目录例如:D:,不同磁盘对应的目录不一样


49.png

B、测试硬盘读流量,即从Windows2008机器下载文件至本机,且限制速度为1024KB/秒(限速的目的是为了使数据稳定,便于测试)


9.png
10.png
C、通过Python脚本查看读次数,在Python脚本所在目录,执行命令:python3 view.py io(或者python view.py io),打出的日志中,“read_count”即为硬盘读次数
# -*- coding: utf-8 -*-  
 
import psutil
import collections
import time
import os,sys
 
def get_os_info():
    #开机时间
    boot_time = psutil.boot_time()
    
 
def get_cput_info():    
    cpu = psutil.cpu_times_percent(interval=1.00)
    cpu_percent_every = psutil.cpu_percent(interval=1,percpu=True)
    cpu_percent = psutil.cpu_percent(interval=1)
    return "{'user':"+str(cpu.user)+",'system':"+str(cpu.system)+",'idle':"+str(cpu.idle)+"'physical_count':"+str(psutil.cpu_count(logical=False))+"'logic_count':"+str(psutil.cpu_count())+",cpu_percent:"+str(cpu_percent)+",cpu_percent_every:"+str(cpu_percent_every)+"}"
    
 
def get_mem_info():
    #单位是MB
    mem = psutil.virtual_memory()    
    return "{'total':"+str(mem.total//1024//1024)+"MB,'free':"+str(mem.free//1024//1024)+"MB,'used':"+str(mem.used//1024//1024)+"MB,'use_percent':"+str((mem.used/mem.total)*100)+"%}"
 
 
def get_disk_info():
    """
    获取磁盘属性信息
    :return: json样例如下
    {
    "total": 100,   //磁盘总大小GB
    "used": 20,     //磁盘使用大小GB
    "partitions": [{  //各分区情况
        "name": "c",   //分区名称
        "total": "30",  //分区大小GB
        "free": "10"    //分区还剩空间GB
    }, {
        "name": "d",
        "total": "30",
        "free": "10"
    }]
     }    
    """ 
    json = ""
    partitions = "["
    disk_total = 0
    disk_free = 0
    disk_used = collections.OrderedDict()
    
    for id in psutil.disk_partitions():
        if 'cdrom' in id.opts or id.fstype == '':
            continue
        disk_name = id.device.split(':')
        s = disk_name[0]
        disk_info = psutil.disk_usage(id.device)
        disk_total = disk_total + (disk_info.total // 1024 // 1024 // 1024)
        disk_free = disk_free + (disk_info.free // 1024 // 1024 // 1024)       
        
        partitions = partitions + "{'name':'"+s+"','total':"+str(disk_info.total // 1024 // 1024 // 1024)+",'free':"+str(disk_info.free // 1024 // 1024 // 1024)+",'perent':"+str(disk_info.percent)+"},"
    
    
        
    partitions = partitions.rstrip(",")+ "]"
    json = "{'total':"+str(disk_total)+",'free':"+str(disk_free)+",'partitions':"+partitions+"}"    
    return json
 
 
########
# 获取开机以来 接收/发送 的字节数
# 参数(sent): Ture--返回发送的字节数 , False--不返回
# 参数(recv): Ture--返回接收的字节数 , False--不返回
# 两个参数都为(True): 返回包含 接收/发送 字节数的列表
# 函数失败返回: None
def io_get_bytes(sent=False,recv=False):
    internet = psutil.net_io_counters()  # 获取与网络IO相关的信息
    if internet == None:                 # 如果获取IO信息失败
        return None
    io_sent = internet.bytes_sent        # 开机以来发送的所有字节数
    io_recv = internet.bytes_recv        # 开机以来接收的所有字节数
    if sent == True and recv == True :
        return [io_sent,io_recv]
    elif sent == True:
        return io_sent
    elif recv == True:
        return io_recv
    else:
        return None                      # 参数不正确, 返回None
 
def get_net_info():
    #单位是KB
    interval = 60                       # 每隔 interval 秒获取一次网络IO信息, 数值越小, 测得的网速越准确
    k = 1024                            # 一 K 所包含的字节数
    m = 1048576                         # 一 M 所包含的字节数    
    byteSent1 = io_get_bytes(sent=True)  # 获取开机以来上传的字节数
    byteRecv1 = io_get_bytes(recv=True)  # 获取开机以来下载的字节数
    #print (byteSent1)
    #print (byteRecv1)
    time.sleep(interval)                                  # 间隔 1 秒                            
    #os.system('cls')                               # 执行清屏命令 
    byteSent2 = io_get_bytes(sent=True)  # 再次获取开机以来上传的字节数
    byteRecv2 = io_get_bytes(recv=True)  # 再次获取开机以来下载的字节数
    sent = (byteSent2-byteSent1)/1024/1024/60                   # interval 秒内所获取的上传字节数 KB
    recv = (byteRecv2-byteRecv1)/1024/1024/60                     # interval 秒内所获取的下载字节数 KB   
    
    return "{'up_speed':"+str(sent)+"MB,'down_speed':"+str(recv)+"MB}"
  
def get_disk_io():
    disk_io_pre = psutil.disk_io_counters()
    time.sleep(1)
    disk_io_now = psutil.disk_io_counters()
    
    r_count = (disk_io_now.read_count-disk_io_pre.read_count)
    w_count = (disk_io_now.write_count-disk_io_pre.write_count)
    r_m =(disk_io_now.read_bytes-disk_io_pre.read_bytes)
    w_m =(disk_io_now.write_bytes-disk_io_pre.write_bytes)
    
    return ('"read_count:"%s,"write_count:"%s,"read_byte:"%s,"write_byte:"%s')%(str(r_count),str(w_count),str(r_m),str(w_m))
if __name__ == '__main__':
    while True:
        disk_info = get_disk_info
        cpu_info = get_cput_info
        mem_info = get_mem_info
        net_info = get_net_info
        disk_io = get_disk_io
        info = {'cpu':cpu_info,'mem':mem_info,'disk':disk_info,'net':net_info,'io':disk_io}
        print(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())+':  '+info[sys.argv[1]]())
        try:
            print(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())+':  '+info[sys.argv[1]]())
            time.sleep(1)
        except:
            print (
    '''
    Use:
        python view.py [cpu/mem/disk/net/io]
    '''
                )
            break
53.png

D、对比测试数据
截图为腾讯云的数据,仅供参考


14.png
2、测试硬盘写次数:

A、用工具FlashFXP工具连接到开启了ftp服务的目录例如:D:,不同磁盘对应的目录不一样


49.png

B、测试硬盘读流量,即从本机上传文件至Windows2008机器,且限制速度为1024KB/秒(限速的目的是为了使数据稳定,便于测试)


9.png
10.png
C、通过Python脚本查看写次数,在Python脚本所在目录,执行命令:python3 view.py io(或者python view.py io),打出的日志中,“write_count”即为硬盘写次数
# -*- coding: utf-8 -*-  
 
import psutil
import collections
import time
import os,sys
 
def get_os_info():
    #开机时间
    boot_time = psutil.boot_time()
    
 
def get_cput_info():    
    cpu = psutil.cpu_times_percent(interval=1.00)
    cpu_percent_every = psutil.cpu_percent(interval=1,percpu=True)
    cpu_percent = psutil.cpu_percent(interval=1)
    return "{'user':"+str(cpu.user)+",'system':"+str(cpu.system)+",'idle':"+str(cpu.idle)+"'physical_count':"+str(psutil.cpu_count(logical=False))+"'logic_count':"+str(psutil.cpu_count())+",cpu_percent:"+str(cpu_percent)+",cpu_percent_every:"+str(cpu_percent_every)+"}"
    
 
def get_mem_info():
    #单位是MB
    mem = psutil.virtual_memory()    
    return "{'total':"+str(mem.total//1024//1024)+"MB,'free':"+str(mem.free//1024//1024)+"MB,'used':"+str(mem.used//1024//1024)+"MB,'use_percent':"+str((mem.used/mem.total)*100)+"%}"
 
 
def get_disk_info():
    """
    获取磁盘属性信息
    :return: json样例如下
    {
    "total": 100,   //磁盘总大小GB
    "used": 20,     //磁盘使用大小GB
    "partitions": [{  //各分区情况
        "name": "c",   //分区名称
        "total": "30",  //分区大小GB
        "free": "10"    //分区还剩空间GB
    }, {
        "name": "d",
        "total": "30",
        "free": "10"
    }]
     }    
    """ 
    json = ""
    partitions = "["
    disk_total = 0
    disk_free = 0
    disk_used = collections.OrderedDict()
    
    for id in psutil.disk_partitions():
        if 'cdrom' in id.opts or id.fstype == '':
            continue
        disk_name = id.device.split(':')
        s = disk_name[0]
        disk_info = psutil.disk_usage(id.device)
        disk_total = disk_total + (disk_info.total // 1024 // 1024 // 1024)
        disk_free = disk_free + (disk_info.free // 1024 // 1024 // 1024)       
        
        partitions = partitions + "{'name':'"+s+"','total':"+str(disk_info.total // 1024 // 1024 // 1024)+",'free':"+str(disk_info.free // 1024 // 1024 // 1024)+",'perent':"+str(disk_info.percent)+"},"
    
    
        
    partitions = partitions.rstrip(",")+ "]"
    json = "{'total':"+str(disk_total)+",'free':"+str(disk_free)+",'partitions':"+partitions+"}"    
    return json
 
 
########
# 获取开机以来 接收/发送 的字节数
# 参数(sent): Ture--返回发送的字节数 , False--不返回
# 参数(recv): Ture--返回接收的字节数 , False--不返回
# 两个参数都为(True): 返回包含 接收/发送 字节数的列表
# 函数失败返回: None
def io_get_bytes(sent=False,recv=False):
    internet = psutil.net_io_counters()  # 获取与网络IO相关的信息
    if internet == None:                 # 如果获取IO信息失败
        return None
    io_sent = internet.bytes_sent        # 开机以来发送的所有字节数
    io_recv = internet.bytes_recv        # 开机以来接收的所有字节数
    if sent == True and recv == True :
        return [io_sent,io_recv]
    elif sent == True:
        return io_sent
    elif recv == True:
        return io_recv
    else:
        return None                      # 参数不正确, 返回None
 
def get_net_info():
    #单位是KB
    interval = 60                       # 每隔 interval 秒获取一次网络IO信息, 数值越小, 测得的网速越准确
    k = 1024                            # 一 K 所包含的字节数
    m = 1048576                         # 一 M 所包含的字节数    
    byteSent1 = io_get_bytes(sent=True)  # 获取开机以来上传的字节数
    byteRecv1 = io_get_bytes(recv=True)  # 获取开机以来下载的字节数
    #print (byteSent1)
    #print (byteRecv1)
    time.sleep(interval)                                  # 间隔 1 秒                            
    #os.system('cls')                               # 执行清屏命令 
    byteSent2 = io_get_bytes(sent=True)  # 再次获取开机以来上传的字节数
    byteRecv2 = io_get_bytes(recv=True)  # 再次获取开机以来下载的字节数
    sent = (byteSent2-byteSent1)/1024/1024/60                   # interval 秒内所获取的上传字节数 KB
    recv = (byteRecv2-byteRecv1)/1024/1024/60                     # interval 秒内所获取的下载字节数 KB   
    
    return "{'up_speed':"+str(sent)+"MB,'down_speed':"+str(recv)+"MB}"
  
def get_disk_io():
    disk_io_pre = psutil.disk_io_counters()
    time.sleep(1)
    disk_io_now = psutil.disk_io_counters()
    
    r_count = (disk_io_now.read_count-disk_io_pre.read_count)
    w_count = (disk_io_now.write_count-disk_io_pre.write_count)
    r_m =(disk_io_now.read_bytes-disk_io_pre.read_bytes)
    w_m =(disk_io_now.write_bytes-disk_io_pre.write_bytes)
    
    return ('"read_count:"%s,"write_count:"%s,"read_byte:"%s,"write_byte:"%s')%(str(r_count),str(w_count),str(r_m),str(w_m))
if __name__ == '__main__':
    while True:
        disk_info = get_disk_info
        cpu_info = get_cput_info
        mem_info = get_mem_info
        net_info = get_net_info
        disk_io = get_disk_io
        info = {'cpu':cpu_info,'mem':mem_info,'disk':disk_info,'net':net_info,'io':disk_io}
        print(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())+':  '+info[sys.argv[1]]())
        try:
            print(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())+':  '+info[sys.argv[1]]())
            time.sleep(1)
        except:
            print (
    '''
    Use:
        python view.py [cpu/mem/disk/net/io]
    '''
                )
            break
52.png

D、对比测试数据
截图为腾讯云的数据,仅供参考


23.png
上一篇 下一篇

猜你喜欢

热点阅读