Linux 平均负载

2023-05-16

本文首发自公众号「 LinuxOK 」,ID 为:Linux_ok。
关注公众号第一时间获取更新,分享不仅技术文章,还有关于职场生活的碎碎念。

在 Linux 系统中,所谓平均负载,指的是单位时间内,系统中处于可运行状态和不可中断状态的平均进程数,即平均活跃进程数,确切的说,是指活跃进程数的指数衰减平均值。具体算法暂不关注,这里简单理解为活跃进程数的平均值就可以。

1、uptime 命令的含义

在这里插入图片描述
当前系统时间:13:35:55
系统运行来多长时间:up 4:00
正在登陆的用户数:7 users
过去1分钟、5分钟、15分钟的平均负载:0.15,0.43,0.25

如上,uptime 命令为我们提供了三个不同时间间隔的平均值,方便我们分析系统负载的趋势:
若最近 1 分钟、5 分钟、15 分钟的取值相差不大,说明系统负载平稳;
若最近 1 分钟的值远大于15分钟的值,说明最近 1 分钟的负载在增加,需要我们持续观察分析。
若最近 1 分钟的值远小于 15 分钟的值,说明系统的负载正在减少,15 分值分钟前有很大负载。

举例:在单核 CPU 系统上的平均负载依次为:1.66,0.43,6.32,说明系统负载整体在降低:
系统负载最近 1 分钟内超载: (1.66 - 1) * 100 = 66%
系统负载最近 5 分钟内正常,没有超载
系统负载最近 15 分钟内 (6.32 - 1)* 100 = 532%

在理想情况下平均负载应等于 CPU 的个数,但是当平均负载大于 CPU 个数就说明系统过载了么,这是不确定的,因为在 Linux内核中,平均负载的设计,关注的不仅仅是正在使用 CPU 的进程(CPU使用率),还包括来等待 CPU 和等待 IO 的进程。

为什么要这么设计?这是因为平均负载是为了反映系统对性能的需求量。假设我们想办法降低系统性能,如更换读写速度非常卡慢的磁盘,其他运行的程序、CPU 等都不变,那此时系统反映出来的对性能的需求量理应是增加的,即平均负载呈是增加趋势,然而如果平均负载关注的仅是 CPU 使用率,那就不增反减了。

2、不可中断睡眠状态对平均负载的影响

在前面的文章我们了解到进程的 D状态表示不可中断睡眠状态(Uninterruptible sleep),一般说明进程正跟硬件交互中,我们写一个简单的内核模块来构造进程处于 D 状态的现象,从而验证对系统平均负载的影响。

内核模块代码:

//说明:本代码逻辑并非十分完善,仅为了构造不可中断睡眠状态
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/device.h>
#include <linux/sched.h>

#define DEVICE_NAME "load_average_test"
static int major_num = 0;

static int load_average_test_open(struct inode *inode, struct file *file)
{
    printk("%s\n", __func__);
    return 0;
}

static int load_average_test_release(struct inode *inode, struct file *file)
{
    printk("%s\n", __func__);
    return 0;
}

static ssize_t load_average_test_write(struct file *file,
                               const char *buffer, size_t length, loff_t *offset)
{
    printk("%s %u\n", __func__, length);

    //设置线程为不可中断的睡眠状态
    __set_current_state(TASK_UNINTERRUPTIBLE);
    schedule();

    return length;
}

struct file_operations fops = {
    .owner = THIS_MODULE,
    .open = load_average_test_open,
    .release = load_average_test_release,
    .write = load_average_test_write,
};

int load_average_test_init(void)
{
    printk("kernel load average init.\n");

    major_num = register_chrdev(0, DEVICE_NAME, &fops);
    if (major_num < 0) {
        printk("Registering char device failed with %d\n", major_num);
        return major_num;
    }

    struct class *my_class_class = class_create(THIS_MODULE, DEVICE_NAME);
    if(IS_ERR(my_class_class))
    {
        printk("Err: failed in creating class.\n");
        return -1;
    }

    device_create(my_class_class, NULL, MKDEV(major_num, 0), NULL, DEVICE_NAME);
    return 0;
}

void load_average_test_exit(void)
{
    printk("kernel load average exit.\n");
}

module_init(load_average_test_init);
module_exit(load_average_test_exit);

MODULE_LICENSE("GPL");

Makefile:

obj-m += load_average.o

all:
    make -C /lib/modules/3.10.0-1127.el7.x86_64/build M=$(PWD) modules
clean:
    make -C /lib/modules/3.10.0-1127.el7.x86_64/build M=$(PWD) clean

编译内核代码需要注意,在 /lib/modules/ ( u n a m e − r ) / b u i l d 需 要 有 内 核 代 码 , 否 则 需 要 先 下 载 。 以 我 的 c e n t o s 7 环 境 为 例 , / l i b / m o d u l e s / (uname -r)/build 需要有内核代码,否则需要先下载。以我的 centos7 环境为例,/lib/modules/ (unamer)/buildcentos7/lib/modules/(uname -r)/build 是一个软连接,目标目录并没有相关代码:
在这里插入图片描述
需要执行下载,重新创建软连接:

$ yum -y install kernel-devel.x86_64
$ rm /lib/modules/3.10.0-1127.el7.x86_64/build
$ ln -s /usr/src/kernels/3.10.0-1160.62.1.el7.x86_64 /lib/modules/3.10.0-1127.el7.x86_64/buil

在这里插入图片描述
编译:
在这里插入图片描述
应用程序代码:

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>

int main()
{
    int fd = open("/dev/load_average_test", O_RDWR);
    if (fd < 0) {
        perror("open");
        return -1;
    }

    write(fd, "load_average_test", strlen("load_average_test"));

    close(fd);
    return 0;
}

编译:

$ gcc load_average_app.c -o load_average_app

加载内核模块后执行 load_average_app 程序:

$ insmod kernel_load_average.ko

在这里插入图片描述
此时使用 mpstat 查看系统 CPU 的执行情况,从 %idle为 100.00可知当前 CPU 是处于空闲状态的。

在这里插入图片描述
在使用 uptime 查看平均负载,单核系统下最近一分钟平均负载已经超过 2 了。
在这里插入图片描述

3、总结

平均负载反映的是系统整体的负载情况,日常工作中它是一个快速查看系统整体性能的方法法,而不单指 CPU 性能;比如有时候IO设备出现了瓶颈导致系统出现大量处于等待 IO 状态的进程,也会导致平均负载升高。所以当我们发现平均负载升高时,还要结合 mpstat、top 等命令,分析具体是什么原因导致的,是 CPU 使用率问题还是 IO 问题。

本文首发自公众号「 LinuxOK 」,ID 为:Linux_ok。
关注公众号第一时间获取更新,分享不仅技术文章,还有关于职场生活的碎碎念。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Linux 平均负载 的相关文章

随机推荐

  • 音频处理——G711标准详解

    目录 G711简介G711A算法原理压缩方法举例代码 G711U算法原理压缩方法举例代码 G711A与G711U对比 参考链接 G711简介 G711是国际电信联盟ITU T定制出来的一套语音压缩标准 xff0c 它代表了对数PCM xff
  • PS流详解(载荷H264)

    目录 PS简介标准结构标准H264流结构定长音频帧和其他流式私有数据的结构 PS流封装标准PSH结构PES包结构PSM包结构体 元素流 PS 封装规则H264元素流封装规则音频元素流封装规则私有信息封装规则 PS简介 PS 封装方式需要支持
  • Postman中的authorization

    1 概述 Authorization是验证是否拥有从服务器访问所需数据的权限 当发送请求时 xff0c 通常必须包含参数 xff0c 以确保请求具有访问和返回所需数据的权限 Postman提供了授权类型 xff0c 可以轻松地在Postma
  • 操作pdf,提示startxref not found

    startxref not found多半是文件被损坏了 xff0c 检查一下 xff0c 是不是之前自己写的代码把pdf文件跑崩了 可以尝试重新生成一遍该pdf文件 xff0c 然后再进行操作 或者尝试一下 xff1a https www
  • FTP 530未登录

    提供一种思路 xff1a 如果说FTP服务器已开 xff0c 服务器也能ping通 就得考虑是不是我们在FTP服务器上设置的默认路径有问题 xff08 不符合我们的需求 xff09 Windows10下 xff0c FTP设置默认位置 xf
  • 开源个小demo

    https github com UnderADome epms 内部项目管理
  • LDAP的基本知识

    https zhuanlan zhihu com p 147768058 https www cnblogs com gaoyanbing p 13967860 html
  • 「权威发布」2019年电赛最全各类题目细节问题解答汇总

    点击上方 大鱼机器人 xff0c 选择 置顶 星标公众号 福利干货 xff0c 第一时间送达 xff01 各位朋友大家上午好 xff0c 今天是比赛的第二天 xff0c 许多朋友都给我发消息 xff0c 我不是不回 xff0c 我实在是回不
  • Unable to find explicit activity class

    做项目从一个activity逐渐转向到使用多个activity xff0c 这个时候新手就容易出现一个问题 xff0c 忘了给activity在AndroidManifest xml中注册 打开日志 xff0c 在遇到这个报错信息的时候 x
  • Errors running builder 'Maven Project Builder'

    由于第一次玩maven的时候 xff0c 很多东西都还是懵懵懂懂 xff0c 不是很清楚 xff0c 不知道怎么把Myeclipse中的maven配置弄坏了 xff0c 从外部导入maven项目的时候 xff0c 总会报一些错误 xff1a
  • Type handler was null on parameter mapping for property '__frch_id_0'

    1 Type handler was null on parameter mapping for property frch id 0 2 Type handler was null on parameter mapping or prop
  • 如何解决error: failed to push some refs to 'xxx(远程库)'

    在使用git 对源代码进行push到gitHub时可能会出错 xff0c 信息如下 此时很多人会尝试下面的命令把当前分支代码上传到master分支上 git push u origin master 但依然没能解决问题 出现错误的主要原因是
  • expected an indented block

    Python中没有分号 xff0c 用严格的缩进来表示上下级从属关系 导致excepted an indented block这个错误的原因一般有两个 xff1a 1 冒号后面是要写上一定的内容的 xff08 新手容易遗忘这一点 xff09
  • C 实现TCP服务端(select、poll、epoll)

    使用C简单的实现一个tcp server xff0c 包括常规server 多线程实现server select实现server poll实现server epoll实现server IO模型原理可以看上一篇文章 常规模式 define M
  • UART串口通信

    目录 一 通信特点二 通信应用三 接线示意图三 UART通信协议四 STM32F4 串口使用1 资源分布2 特性3 UART框图4 使用方法5 相关库函数6 函数实例 五 实战 上位机控制开发板小灯 一 通信特点 异步 串行 全双工 一般描
  • 项目:文件搜索助手(FileSeeker)

    目录 1 项目简介 2 项目源代码 3 相关技术 4 实现原理 5 项目架构图 6 项目功能 7 测试报告 7 1 测试用例 7 2 测试环境 7 3 测试结论 7 3 1 功能测试 7 3 2 性能测试 7 3 3 兼容性 7 3 4 容
  • cocos2d实现2D地图A*广度路径算法

    h ifndef HELLOWORLD SCENE H define HELLOWORLD SCENE H include 34 cocos2d h 34 USING NS CC enum PatchFront Uper 61 1 Down
  • Keil 中,仿真调试查看局部变量值总是显示<not in scope>

    原因 xff1a 编译器把代码优化掉了 xff0c 直接导致在仿真中变量根本没有分配内存 xff0c 也就无法查看变量值 以后调试中遇到这种情况的解决办法 xff1a 核心思想是 xff1a 让变量值在代码中被读取其内存值 1 把变量定义为
  • 联合体在串口通讯中的妙用

    背景 本文主要涉及到的是一种串口通讯的数据处理方法 xff0c 主要是为了解决浮点数在串口通讯中的传输问题 xff1b 通常而言 xff0c 整形的数据类型 xff0c 只需进行移位运算按位取出每个字节即可 xff0c 那么遇到浮点型的数据
  • Linux 平均负载

    本文首发自公众号 LinuxOK xff0c ID 为 xff1a Linux ok 关注公众号第一时间获取更新 xff0c 分享不仅技术文章 xff0c 还有关于职场生活的碎碎念 在 Linux 系统中 xff0c 所谓平均负载 xff0