创建没有Cron作业的计划任务

时间:2014-04-12 09:51:07

标签: php mysql cron

需要创建计划任务,但不能使用Cron作业(托管服务提供商发出警告,"在45分钟内不止一次运行cron作业违反了他们的规则和可能会导致关闭帐户。"

应该每分钟执行一次php脚本(从txt到mysql数据库插入数据),即应该调用此链接http://www.myserver.com/ImportCumulusFile.php?type=dayfile&key=letmein&table=Dayfile&file=./data/Jan10log.txt

还有其他办法吗?

5 个答案:

答案 0 :(得分:6)

有多种方法可以重复工作。我能立刻想到的一些方法是:

  1. 使用:https://www.setcronjob.com/
  2. 使用此类外部网站按设定的时间间隔启动您的网址

    1. 使用元刷新。更多here。您必须打开该页面并让其继续运行。

    2. Javascript / Ajax刷新。与上面的例子类似。

    3. 设置cron作业。大多数共享托管确实提供了一种设置cron作业的方法。看看你托管的cPanel。

答案 1 :(得分:3)

如果你有shell访问权限,你可以通过shell执行php脚本

这样的事情将是一个无限循环,它会睡60秒执行,收集垃圾并重复直到时间结束。

while(true) {
    sleep(60);
    //script here


    //end your script
}

或者你可以做一个"穷人的cron"使用ajax或元刷新。我以前做过。基本上,您只需在脚本开始时使用javascript或html的元刷新进行重定向。从您的浏览器访问此脚本,然后将其保持打开状态。它会每60秒刷新一次,就像一个cronjob。

cronjob的另一种替代方法是bash脚本,例如:

#!/bin/bash
while :

do
sleep 60
 wget http://127.0.0.1/path/to/cronjob.php -O Temp --delete-after

done

所有这一切都说,你可能会被主持人抓住并终止。

所以你最好的解决方案:

去报名参加每月5-10美元的vps,然后再告诉共享主机,并问好你自己的小服务器。

如果你这样做,你甚至可以停止使用蹩脚的php并使用facebook的hhvm来享受其出色的表现。

答案 2 :(得分:1)

据我所知,这个问题有点陈旧,但我在一周前偶然发现了这个问题,我们发现最好和最安全的选择是使用Web服务。

我们的背景:

我们的系统包含共享托管和私有云。

我们需要在一个月内激活一次脚本(计划创建更多计划并允许用户创建一些预定的操作)

我们的系统提供对许多客户端的访问,因此,当任何人使用系统时,它通过Ajax调用Web服务并且不关心响应(毕竟所有内容都记录在我们的数据库中,并且必须在没有用户的情况下运行相互作用)

我们所做的是:

1 - 在任何主要屏幕上访问时调用ajax调用。

2 - Web服务在我们的数据库上读取一个调度表,并调用所需的任何调用

3 - 为了避免许多堆叠的Web服务调用,我们在实际执行任何操作之前以10分钟的间隔检查日期时间

这也是一种分配负载均衡和计划的方法,不会影响系统与用户的交互。

答案 3 :(得分:0)

提供免费服务

http://cron-job.org

这可以让你设置一个不错的小替代品。

答案 4 :(得分:0)

选项A

实现它的一种简单方法是创建一个包含php脚本执行时间的文件/数据库条目:

<?php
// crons.php
return [
    'executebackup.php' => 1507979485,
    'sendnewsletter.php' => 1507999485
];
?>

对于通过访问者发出的每个请求,您都会检查当前时间,如果它包含您的PHP脚本,则更高:

<?php
// cronpixel.php
$crons = @include 'cache/crons.php';
foreach ($crons as $script => $time) {
    if ($time < time()) {
        // create lock to avoid race conditions
        $lock = 'cache/' . md5($script) . '.lock';
        if (file_exists($lock) || !mkdir($lock)) {
            continue;
        }
        // start your php script
        include($script);
        // now update crons.php
        $crons[ $script ] += 86400; // tomorrow
        file_put_contents('cache/crons.php', '<?php return ' . var_export($crons, true) . '; ?' . '>')
        // finally delete lock
        rmdir($lock);
    }
}
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
// image data
$im = imagecreate(1, 1);
$blk = imagecolorallocate($im, 0, 0, 0);
imagecolortransparent($im, $blk);
// image output
header("Content-type: image/gif");
imagegif($im);
// free memory
imagedestroy($im);
?>

注意:它会在第二天被激活地调用,因为您不知道访问者何时打开您的页面(可能是2秒钟后)。因此,为第二天设置新时间而不是添加86400秒是有意义的。而是使用mktime

选项B

This is a little project我在过去意识到,这与@ r3wt的想法相似,但是它涵盖了竞争条件,并且在确切时间内工作,就像cronjob在调度程序中所做的那样,而没有点击max_execution_time。它大部分时间都可以工作,而不需要复活它(如选项A中的访问者所做的那样)。

说明: 该脚本在15分钟,30分钟,45分钟和60分钟内写入一个锁定文件(以避免竞争条件):

// cron monitoring
foreach ($allowed_crons as $cron_second) {
    $cron_filename = 'cache/' . $cron_second . '_crnsec_lock';
    // start missing cron requests
    if (!file_exists($cron_filename)) {
        cron_request($cron_second);
    }
    // restart interrupted cron requests
    else if (filemtime($cron_filename) + 90 < time()) {
        rmdir($cron_filename);
        cron_request($cron_second);
    }
}

每次缺少锁定文件时,脚本都会创建该文件并使用sleep()来达到确切的秒数:

if (file_exists($cron_filename) || !mkdir($cron_filename)) {
    return;
}
// add one minute if necessary
$date = new DateTime();
$cron_date = new DateTime();
$cron_date->setTime($cron_date->format('H'), $cron_date->format('i'), $sec);
$diff = $date->diff($cron_date);
if ($diff->invert && $diff->s > 0) {
    $cron_date->setTime($cron_date->format('H'), $cron_date->format('i') + 1, $sec);
}
$diff = $date->diff($cron_date);
// we use sleep() as time_sleep_until() starts one second to early (https://bugs.php.net/bug.php?id=69044)
sleep($diff->s);

再次醒来后,它会通过fopen()向自己发送请求:

// note: filter_input returns the unchanged SERVER var (http://php.net/manual/de/function.filter-input.php#99124)
// note: filter_var is unsecure (http://www.d-mueller.de/blog/why-url-validation-with-filter_var-might-not-be-a-good-idea/)
$url = 'http' . isSecure() . '://' . filter_input(INPUT_SERVER, 'HTTP_HOST', FILTER_SANITIZE_URL) . htmlspecialchars($request_uri, ENT_QUOTES, 'UTF-8');
$context = stream_context_create(array(
    'http' => array(
        'timeout' => 1.0
    )
));
// note: return "failed to open stream: HTTP request failed!" because timeout < time_sleep_until
if ($fp = @fopen($url, 'r', false, $context)) {
    fclose($fp);
}
rmdir($cron_filename);

通过它无限地调用自己,你可以定义不同的开始时间:

if (isset($_GET['cron_second'])) {
    if ($cron_second === 0 && !(date('i') % 15)) {
        mycron('every 15 minutes');
    }
    if ($cron_second === 0 && !(date('i') % 60)) {
        mycron('every hour');
    }
}

注意:它每天产生5760个请求(每分钟4个)。不多,但一个cronjob使用更少的资源。如果您的max_execution_time足够高,您可以将其更改为每分钟调用一次(每天1440个请求)。

相关问题