首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >只在机器空闲时运行cron作业(linux)

问只在机器空闲时运行cron作业(linux)
EN

Stack Overflow用户
提问于 2013-01-14 19:57:32
回答 2查看 4K关注 0票数 5

当CPU空闲超过50%时,我如何才能运行cron作业(bash脚本)?

我可以让cpu从顶部空闲

代码语言:javascript
复制
top -b -d 00.10 -n 3 |grep ^Cpu
Cpu(s): 0.3%us, 0.3%sy, 0.0%ni, 99.3%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st

我目前的设置是:

代码语言:javascript
复制
crontab
0,15,30,45 * * * * /usr/bin/php /home/user/batchprocess.php
# I could use a bash script here to call PHP, if it is a good solution.

我让PHP脚本检查CPU空闲:

代码语言:javascript
复制
batchprocess.php
proc_nice(10);
// wait for CPU idle
do{
    $cpu_stat = exec('top -b -d 00.10 -n 3 |grep ^Cpu');    
    $tmp = stristr($cpu_stat,'%id',TRUE);
    $cpuidle = trim(substr($tmp,strrpos($tmp,',')+1));
}while($cpuidle<$min_cpuidle);
// do actual processing here

我现在的方法的问题是,不管CPU的利用率如何,它都会启动程序。而同时循环运行的顶部感觉没有效率。我希望它只在CPU idle>50启动时才开始。

一些补充信息:

  • Centos 6.2,PHP5.3
  • 我有一些从未关闭过的EC2实例,所以我想在空闲时利用它们的处理能力。但永远不要沉重地加载服务器。(冗余DB实例、开发实例、NAT实例)
  • 我知道EC2自动缩放,点实例。只是想利用额外的容量。
  • 背景工作是图像压缩(CPU密集,I/O或网络不多)。

任何建议都是欢迎的。提前谢谢!

基于下面的输入,我意识到在我的情况下,“尼斯”是一个更好的解决方案。我应该重新调整我的目标,以尽量减少对服务器的影响,而不是跟踪CPU利用率。

因此,新的设置是:

代码语言:javascript
复制
crontab
0,15,30,45 * * * * nice -20 /usr/bin/php /home/user/batchprocess.php

和PHP脚本:

代码语言:javascript
复制
batchprocess.php
if ($cpuidle < 50) 
    exit(0);
// do actual processing here

我会测试它并把我的发现发回去。

返回:我已经把这个代码通过DEV/PRD,它运行得很好。它不能解决TOCTOU的问题,但现在已经足够了。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-01-14 20:23:01

这是一个典型的托托案例--您检查系统是否空闲,并启动您的进程--但是在您的检查之后,在您的进程开始之前,其他的事情会导致系统中的另一个进程启动,并且您仍然在超出必要的情况下加载系统。

要做到这一点,“正确”的方法是使用nice命令使进程具有较低的优先级。顺便说一句,检查cpu使用率的循环将使用100%的cpu,所以除非第一次检查它是空闲的,否则它可能无法工作。

您已经有了一个"proc_nice(10)",这样就可以完成任务了。我认为没有必要花费精力来确定系统是否繁忙。

如果您在代码中的适当点查看,您可以执行以下操作:

代码语言:javascript
复制
 if (check_cpu_usage() > 50%) sleep(1second); 

但我不确定这是否有多大用处--如果系统很忙,一个“很好”的进程将不会收到太多的CPU时间,因此不会与其他优先级更高的进程竞争。

票数 7
EN

Stack Overflow用户

发布于 2013-04-01 13:33:14

如果您只是希望在系统加载(例如2.0或更少)时执行您的脚本,您可以使用这样的shell脚本:

代码语言:javascript
复制
#!/bin/sh
LOAD=`cat /proc/loadavg | cut -d" " -f1`
THRESHOLD=2.0
if [ $(bc <<< "$LOAD <= $THRESHOLD") -eq 1 ]; then
    $@
fi

将其保存为例如/usr/local/bin/if-idle,并将if-idle放在命令前面的crontab文件中。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14325671

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档