CPU告警不用愁,用C语言编写CPU使用率限制程序

news2024/11/27 1:58:43

现在云服务已经深入千家万户了,不仅商用,私用也很多。很多云服务厂商也都有配套的服务器安全模块,可以检测网络流量异常、内存占用量和CPU占用率,并且允许人工设置告警阈值。例如,CPU持续大于90%10分钟,那么你可能就会收到一条告警通知。

有时,或许这样的告警是因为一些恶意行为或者bug导致。但是有时,我们希望我们编写的程序能够尽可能压榨性能去尽快处理一些工作,此时CPU占满或许是一个很正常的行为。可如此就会触发告警,加之一些同道告警强迫症发作,此时就会很为难。如果增加一些sleep操作,莫名其妙的睡眠似乎总是不够优雅与完美。
在这里插入图片描述那么,有没有什么好的解决方案呢?

今天码哥就给大家提供一种解决方案。
在这里插入图片描述
或许有些人听过用过docker,docker容器就是可以做到资源隔离与资源配额的。似乎是我们想要的,那么是否可以借鉴一下呢?

答案是肯定的。

很多时候,我们的程序只是一次性的任务,且有些任务还依赖一些框架,如果将这种任务装入docker容器运行,显然成本和收益的问题让我们内心不太通达。

在Linux中,这样的资源配额限制是通过cgroups来实现的,它能够限制CPU、内存、IO等资源的使用程度。当然cgroups还有一些其他的使用功能,这里就不额外延展啦。

为了应对上面的那种资源限制需求,码哥展示一个用C语言编写的启动程序,帮你轻松解决这类问题。
在这里插入图片描述
限于篇幅,我们只展示CPU限制的方式,内存和IO相关的限制方法与其类似,可参阅网上一些人的文章自行扩展。

下面直接上代码(受限于手机屏幕尺寸,建议大家PC端查看):

/*
 * Author: 码哥比特
 */
#define _GNU_SOURCE
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/mount.h>
#include <sched.h>
#include <errno.h>
#include <string.h>
#include <dirent.h> 
#include <stdlib.h>
#include <sys/stat.h>

char *cpu = NULL;
char *group_name = NULL;
char cpu_basedir[256];
int deleted = 0;

static void print_help(char *name)
{
    printf("Usage:\n");
    printf("%s [OPTIONS] SHELL COMMAND\n", name);
    printf("\t-c\t\tset cpu rate\n");
    printf("\t-g\t\tgroup name\n");
    printf("\t-d\t\tdelete group\n");
}

static int parse_args(int argc, char *argv[])
{
    //...掠过一些参数解析部分
}

static void set_limit(void)
{
    int fd, n, pid = getpid();
    char tmp[1024];

    if (cpu != NULL) {
        if (mkdir(cpu_basedir, S_IRWXU) < 0) {
            if (errno != EEXIST) {
                fprintf(stderr, "create cpu group failed");
                exit(1);
            }
        }
        memset(tmp, 0, sizeof(tmp));
        snprintf(tmp, sizeof(tmp)-1, "%s/cpu.cfs_quota_us", cpu_basedir);
        if ((fd = open(tmp, O_WRONLY)) < 0) {
            fprintf(stderr, "open cpu file failed. %s\n", strerror(errno));
            exit(1);
        }
        memset(tmp, 0, sizeof(tmp));
        n = snprintf(tmp, sizeof(tmp)-1, "%s\n", cpu);
        write(fd, tmp, n);
        close(fd);

        memset(tmp, 0, sizeof(tmp));
        snprintf(tmp, sizeof(tmp)-1, "%s/tasks", cpu_basedir);
        if ((fd = open(tmp, O_WRONLY|O_APPEND)) < 0) {
            fprintf(stderr, "open cpu tasks failed. %s\n", strerror(errno));
            exit(1);
        }
        memset(tmp, 0, sizeof(tmp));
        n = snprintf(tmp, sizeof(tmp)-1, "%d\n", pid);
        write(fd, tmp, n);
        close(fd);
    }
}

int main(int argc, char *argv[])
{
    int idx = parse_args(argc, argv);
    if (group_name == NULL) {
        fprintf(stderr, "group name must be given\n");
        print_help(argv[0]);
        exit(1);
    }
    memset(cpu_basedir, 0, sizeof(cpu_basedir));
    snprintf(cpu_basedir, sizeof(cpu_basedir)-1, "/sys/fs/cgroup/cpu/%s", group_name);
    if (deleted) {
        remove(cpu_basedir);
    }
    if (idx) {
        set_limit();
        execv(argv[idx], argv+idx);
    }
    return 0;
}

为了节省篇幅,代码中略过了一些参数解析部分。从帮助信息中,我们也可大致看到程序的使用方式。

# ./cpuctl -c=89000 -g=test_group a.out  #姑且先叫cpuctl吧

这里,-g是用来设置资源组名的,避免和其他资源组冲突。-c是这个资源组下的所有进程CPU占用总和的上限数值,89000是89%的含义。这里要注意,如果你有两个进程在这个资源组下,那么两个进程是平分89%的,也就是每个进程44.5%。a.out则是我们要执行的程序。

我们用一个简单的死循环来测试一下:

#include <stdio.h>

int main(void)
{
    while (1) {}
    return 0;
}

正常情况下100%无疑,如图:
在这里插入图片描述
下面我们用我们的程序启动器来启动a.out并限制其CPU为89%,如图:
在这里插入图片描述
我们可以看到,其CPU占比会在89%上下小幅浮动,大家可自行尝试。

从代码中,我们可以看到,其实限制的方法是在/sys/fs/cgroup/cpu下建立一个test_group目录,然后向其内的cfs_quota_us文件写入限制额度,再向其内的tasks写入希望限制的进程ID。目前从码哥的使用情况来看,阿里和腾讯的cgroups配置都是在/sys/fs/cgroup中的,可能其他的操作系统有不同的路径。

喜欢的朋友可以关注码哥,也可以在评论区给码哥留言交流,谢谢观看!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1318903.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

LLM大语言模型(二):Streamlit 无需前端经验也能画web页面

目录 问题 Streamlit是什么&#xff1f; 怎样用Streamlit画一个LLM的web页面呢&#xff1f; 文本输出 页面布局 滑动条 按钮 对话框 输入框 总结 问题 假如你是一位后端开发&#xff0c;没有任何的web开发经验&#xff0c;那如何去实现一个LLM的对话交互页面呢&…

学生管理系统--课程设计项目(Java+SQL server)

本科参与项目文档合集: 点击跳转~ 学生管理系统 Student Management System 学校&#xff1a;山东科技大学 指导老师&#xff1a;杨 * * 教授 学号&#xff1a;2019032**** 学生姓名&#xff1a;安** 专业班级&#xff1a;计算机19-1 山东科技大学 二〇二〇年七月 项目文档目录…

eNSP小实验--实现全网互通

目录 一、建立以下拓扑图&#xff0c;并实现全网互通 二、分析 1、接入层交换机SW4、SW5划分vlan 2、汇聚层交换机SW2,SW3配置ip作为vlan网关&#xff0c;与SW1直连 3、核心交换机SW1配置ip 与汇聚层交换机和R1直连 4、SW1,SW2,SW3,R1配置静态路由&#xff0c;使得vlan10,…

京东体育用品销售数据分析与可视化系统

京东体育用品销售数据分析与可视化系统 前言数据爬取模块1. 数据爬取2. 数据处理3. 数据存储 数据可视化模块1. 数据查看2. 店铺商品数量排行3. 整体好评率4. 不同品牌市场占比5. 品牌差评率排名6. 品牌价格排名7. 品牌评论数量分布 创新点 前言 在体育用品行业&#xff0c;了…

IDEA卡顿,进行性能优化设置(亲测有效)——情况一

需求场景 IDEA重新激活后&#xff0c;运行IDEA卡的非常卡顿&#xff0c;没有运行项目&#xff0c;CPU占比也非常高: 原因分析 可能的原因是&#xff0c;在IDEA的配置中&#xff0c;给他分配的空间比较小 解决方式 步骤一 选择顶部导航栏中的Help&#xff0c;然后点击Edi…

小项目:迷宫二

目录 引言一、题目描述二、解题思路三、代码实现四、测试 引言 这个迷宫项目是今天参加学校的一个比赛出的题目&#xff0c;从早上九点基本搞到了四五点才完成&#xff0c;其实写出来发现基本思路其实挺简单的&#xff0c;就是想不好想&#xff0c;真的要各种的尝试&#xff0…

【数据分析之Numpy】Numpy中复制函数numpy.repeat()与numpy.tile()的使用方法及区别

一、简介 numpy.repeat()与numpy.tile()都是Numpy库中的复制函数&#xff0c;用于将数组中的元素重复指定的次数。 numpy.repeat()函数接受三个参数&#xff1a;要重复的数组、重复的次数和重复的轴。 numpy.tile()函数接受两个参数&#xff1a;要重复的数组和重复的次数。 二…

C语言学习第二十六天(算法的时间复杂度和空间复杂度)

1、算法效率 衡量一个算法的好坏&#xff0c;是从时间和空间两个方面来衡量的&#xff0c;换句话说就是从时间复杂度和空间复杂度来衡量的 这里需要补充一点&#xff1a;时间复杂度是衡量一个算法的运行快慢&#xff0c;空间复杂度是主要衡量一个算法运行所需要的额外空间。 …

面试 Java 算法高频题五问五答第一期

面试 Java 算法高频题五问五答第一期 作者&#xff1a;程序员小白条&#xff0c;个人博客 相信看了本文后&#xff0c;对你的面试是有一定帮助的&#xff01; ⭐点赞⭐收藏⭐不迷路&#xff01;⭐ 1&#xff09;括号生成: 数字 n 代表生成括号的对数&#xff0c;请你设计一个…

neuq-acm预备队训练week 10 P1129 [ZJOI2007] 矩阵游戏

题目描述 小 Q 是一个非常聪明的孩子&#xff0c;除了国际象棋&#xff0c;他还很喜欢玩一个电脑益智游戏――矩阵游戏。矩阵游戏在一个 nn 黑白方阵进行&#xff08;如同国际象棋一般&#xff0c;只是颜色是随意的&#xff09;。每次可以对该矩阵进行两种操作&#xff1a; 行…

STM32F103RCT6开发板M3单片机教程04--按键检测

原画图讲解 本教程使用是&#xff08;光明谷SUN_STM32mini开发板&#xff09; 首先了硬件连接原理&#xff0c;STM32F103RCT6开发板是mini最小系统板&#xff0c;板子在没并有按键。需要自行用面包板搭建。 硬件连接&#xff1a; PC10 -> KEY1 &#xff08;MCU内部上拉…

创投课程第五期 | 超越比特币:探索BTC生态的无限可能

协会邀请了来自水滴资本&#xff08;Waterdrip Capital&#xff09;的投资总监——Elaine&#xff0c;作为VC创投课程第5期的嘉宾&#xff0c;在北京时间12月17日(周日)晚上21:00 PM-22:00 PM&#xff0c;届时将与所有对Web3投资、创业心怀热忱的朋友们共同探讨《超越比特币&am…

TCP/IP详解——DNS 流量分析

文章目录 1. DNS 流量分析1.1 DNS 基本概念1.2 DNS 系统特性1.3 DNS 效率问题1.4 域名的组成1.5 域名解析系统1.5.1 域名解析过程 1.6 DNS 记录种类1.7 DNS 的报文格式1.7.1 DNS 报文中的基础结构部分1.7.2 DNS 查询报文中的问题部分1.7.3 DNS 响应报文中的资源记录部分1.7.4 示…

Unity中URP下的菲涅尔效果实现(个性化修改)

文章目录 前言一、我们修正一下上篇文章中&#xff0c;可能遗留的Bug1、N向量 变为 单位向量2、使颜色范围在合理区间 二、实现菲涅尔效果强弱可自定义调节三、修改菲涅尔效果颜色1、在属性面板定义颜色属性2、在常量缓冲区申明该参数3、在片元着色器中&#xff0c;用颜色和菲涅…

数据结构 AVL树概念以及实现插入的功能(含Java代码实现)

为啥要有avl树 avl树是在二叉搜索树下的一种进阶形式,是为了防止二叉搜索树在极端情况下产生的链表化的场景,从而在二叉搜索树的基础上,加上了某些条件来阻止这种极端情况的产生,但不是保证完全平衡,而是放开了一定的条件,使得这种情况不那么难以满足.(条件:左右子树的高度差的…

【Vulnhub 靶场】【IA: Keyring (1.0.1)】【中等】【20210730】

1、环境介绍 靶场介绍&#xff1a;https://www.vulnhub.com/entry/ia-keyring-101,718/ 靶场下载&#xff1a;https://download.vulnhub.com/ia/keyring-v1.01.ova 靶场难度&#xff1a;中等 发布日期&#xff1a;2021年07月30日 文件大小&#xff1a;1.1 GB 靶场作者&#xf…

Day63力扣打卡

打卡记录 寻找最近的回文数&#xff08;模拟&#xff09; 链接 class Solution:def nearestPalindromic(self, n: str) -> str:m len(n)candidates [10 ** (m - 1) - 1, 10 ** m 1]selfPrefix int(n[:(m 1) // 2])for x in range(selfPrefix - 1, selfPrefix 2):y …

ArcMap自定义脚本工具箱迁移至ArcGIS pro

本文记录了将ArcMap10.7创建的自定义脚本工具箱&#xff08;.tbx&#xff09;迁移至ArcGIS pro的过程 ArcGIS Pro使用的是python版本与ArcMap不同&#xff0c;前者为python3&#xff0c;后者为python2。由于python3 和 python2 的部分语法不兼容&#xff0c;以及一些地理处理工…

性能测试之Artillery(示例及指标)

官方文档&#xff1a;https://www.artillery.io/docs/get-started/first-test PS:文档挺详细&#xff0c;教程比较全 示例 config:http:extendedMetrics: truetarget: http://127.0.0.1:8005phases:- duration: 10 # 持续时间arrivalRate: 10 # 每秒创建10个用户rampTo: 100 …

【漏洞复现】CVE-2023-6848 kodbox远程命令执行

漏洞描述 kodbox 是一个网络文件管理器。它也是一个网页代码编辑器,允许您直接在网页浏览器中开发网站。您可以在基于 Linux、Windows 或 Mac 的平台上在线或本地运行 kodbox。唯一的要求是要有 PHP 5及以上。 kalcaddle kodbox 中发现漏洞,最高版本为 1.48。它已被宣布为关…