电子商务网站开发开发背景,南通网站制作公司,软件开发怎么自学,全球网站排名现在云服务已经深入千家万户了#xff0c;不仅商用#xff0c;私用也很多。很多云服务厂商也都有配套的服务器安全模块#xff0c;可以检测网络流量异常、内存占用量和CPU占用率#xff0c;并且允许人工设置告警阈值。例如#xff0c;CPU持续大于90%10分钟#xff0c;那么…现在云服务已经深入千家万户了不仅商用私用也很多。很多云服务厂商也都有配套的服务器安全模块可以检测网络流量异常、内存占用量和CPU占用率并且允许人工设置告警阈值。例如CPU持续大于90%10分钟那么你可能就会收到一条告警通知。
有时或许这样的告警是因为一些恶意行为或者bug导致。但是有时我们希望我们编写的程序能够尽可能压榨性能去尽快处理一些工作此时CPU占满或许是一个很正常的行为。可如此就会触发告警加之一些同道告警强迫症发作此时就会很为难。如果增加一些sleep操作莫名其妙的睡眠似乎总是不够优雅与完美。 那么有没有什么好的解决方案呢
今天码哥就给大家提供一种解决方案。 或许有些人听过用过dockerdocker容器就是可以做到资源隔离与资源配额的。似乎是我们想要的那么是否可以借鉴一下呢
答案是肯定的。
很多时候我们的程序只是一次性的任务且有些任务还依赖一些框架如果将这种任务装入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.hchar *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], argvidx);}return 0;
}为了节省篇幅代码中略过了一些参数解析部分。从帮助信息中我们也可大致看到程序的使用方式。
# ./cpuctl -c89000 -gtest_group a.out #姑且先叫cpuctl吧这里-g是用来设置资源组名的避免和其他资源组冲突。-c是这个资源组下的所有进程CPU占用总和的上限数值89000是89%的含义。这里要注意如果你有两个进程在这个资源组下那么两个进程是平分89%的也就是每个进程44.5%。a.out则是我们要执行的程序。
我们用一个简单的死循环来测试一下
#include stdio.hint 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中的可能其他的操作系统有不同的路径。
喜欢的朋友可以关注码哥也可以在评论区给码哥留言交流谢谢观看