0

とを使用してスクリプトを使用して、phpでcronジョブを作成しようとしていignore_user_abort(true);ますset_time_limit(0);。基本は機能しますが、残念ながら、サーバーによって15分後にプロセスが強制終了されます。

今、私はfopenそれが殺される前にページを再び要求することによってこれを回避するために使用しています。これは、最初は期待どおりに機能します(テーブルを切り捨て、ループしてから、id = 2のページをロードします)。id = 2の2番目の行が挿入され、ループが正しく開始されます。残念ながら、2ページ目以降は同じIDを使用し続け、id = 3、4などでは続行されません。

誰かがこれを修正する方法についてのアイデアを持っていますか?

テストに使用するサンプルコード:

<?php
ignore_user_abort(true);
set_time_limit(0);
$interval=1;
$startTime = time();
$maxLoop = 10;
$id = (strlen($_GET['id'])>0) ? trim($_GET['id']) : 1;


require_once('ct2database.php');
ct2database::init();

if ($id==1) {
  //init table
  ct2database::query("TRUNCATE TABLE crontest");
}
ct2database::query("INSERT INTO crontest (Id, Counter, StartDate) VALUES (".$id.", 0, '".date("Y-m-d H:i:s")."')");

//loop
do{
  ct2database::query("UPDATE crontest SET Counter=Counter+1 WHERE id=".$id);
  sleep($interval);
}while($maxLoop--);


$newid = $id+1;
$url = 'http://'.$_SERVER['SERVER_NAME'].$_SERVER['REQUEST_URI'].'?id='.$newid . '&t='.time();

//regular end of loop
ct2database::query("UPDATE crontest SET EndDateRegular='".date("Y-m-d H:i:s")."' WHERE id=".$id);

$context = stream_context_create( array(
  'http'=>array(
    'timeout' => 0.5
  )
));
$fp = fopen($url, 'r', false, $context);


register_shutdown_function('ShutdownHandler');
function ShutdownHandler() {
  global $id;
  //update on shutdown
  ct2database::query("UPDATE crontest SET EndDateShutdown='".date("Y-m-d H:i:s")."' WHERE id=".$id);
}

set_error_handler("ErrorHandler"); 
function ErrorHandler() {
  global $id;
  //update on error
  ct2database::query("UPDATE crontest SET EndDateError='".date("Y-m-d H:i:s")."' WHERE id=".$id);
}

?>

そして結果:

Array
(
    [Id] => 1
    [Counter] => 10
    [DateModified] => 2012-12-21 16:01:54
    [StartDate] => 2012-12-21 16:01:42
    [EndDateRegular] => 2012-12-21 16:01:53
    [EndDateShutdown] => 2012-12-21 16:01:54
    [EndDateError] => 0000-00-00 00:00:00
)
Array
(
    [Id] => 2
    [Counter] => 55
    [DateModified] => 2012-12-21 16:02:49
    [StartDate] => 2012-12-21 16:01:54
    [EndDateRegular] => 2012-12-21 16:02:49
    [EndDateShutdown] => 2012-12-21 16:02:49
    [EndDateError] => 0000-00-00 00:00:00
)
4

1 に答える 1

1

この小さな例でスクリプトを「再起動」してみましたが、これまでのところ正常に機能しました。

<?php
if (isset($_GET['id'])) {
    $id = $_GET['id'];
} else {
    $id = 1;
}

echo "$id ";
++$id;
$url = 'http://' . $_SERVER['SERVER_NAME'] . $_SERVER['PHP_SELF'] . '?id=' . $id;

if ($id < 10) {
    $fp = fopen($url, 'r');
    $buf = fread($fp, 100);
    echo $buf;
    fclose($fp);
}

ただし、パラメータを含む完全なパスが含まれているPHP_SELFため、を使用しました。これは、のようなURLになります。スクリプトからの出力も読み取ります。そうしないと、出力が発生したときにブロックされる可能性があります。REQUEST_URIidhttp://server/path?id=1?id=2?id=3?id=...

覚えておくべきもう1つのポイントは、これは事実上無限の再帰であるということです。これにより、connection refusedエラーが発生する場合があります。

したがって、実際の解決策は、サーバーログを調べて、問題の本当の理由を見つけることです。

于 2012-12-21T16:09:39.263 に答える