2

長時間の仕事をしたいのですが、最大実行時間を変更できないので、解決策を講じます。スクリプトがシャットダウンしようとすると、スクリプトは自分自身に http 要求を送信するため、スクリプトは引き続き実行できます。 これは私のテストスクリプト t.php です

<?php 
define('DS', DIRECTORY_SEPARATOR);
define('ROOT', dirname(__FILE__));

function post_request_async($url, ARRAY $data) {
    // Convert the data array into URL Parameters like a=b&foo=bar etc.
    $data = http_build_query($data);
    // parse the given URL
    $url = parse_url($url);
    $host = $url['host'];
    $path = $url['path'];
    $port = isset($url['port']) ? $url['port'] : "80";
    $fp = fsockopen($host, $port, $errno, $errstr, 5);
    if ($fp){
        $req = "";
        $req.="POST $path HTTP/1.0\r\n";
        $req.="Host: $host\r\n";
        $req.="Content-type: application/x-www-form-urlencoded\r\n";
        $req.="Content-length: ". strlen($data) ."\r\n";
        $req.="Connection: close\r\n\r\n";
        $req.= $data;
        fputs($fp, $req);
        fclose($fp);
    }
}

set_time_limit(10);
register_shutdown_function("shutdown_func");

file_put_contents(ROOT.DS."zz.txt", date("Y-m-d H:i:s")." start -->".PHP_EOL, FILE_APPEND);

function shutdown_func(){
    file_put_contents(ROOT.DS."zz.txt", date("Y-m-d H:i:s")." shutdown_func -->".PHP_EOL, FILE_APPEND);
    post_request_async("http://127.0.0.1/t.php", array());
    exit();
}

for(;;) {
    sleep(2);
}
?>

しかし、結果は奇妙です: zz.txt

2012-05-16 10:11:42 start -->
2012-05-16 10:11:54 shutdown_func -->
2012-05-16 10:11:54 start -->
2012-05-16 10:12:04 shutdown_func -->
2012-05-16 10:12:04 start -->
2012-05-16 10:12:14 shutdown_func -->
2012-05-16 10:12:14 start -->
2012-05-16 10:12:26 shutdown_func -->
2012-05-16 10:12:26 start -->
2012-05-16 10:12:38 shutdown_func -->
2012-05-16 10:12:38 start -->
2012-05-16 10:12:48 shutdown_func -->
2012-05-16 10:12:48 start -->
2012-05-16 10:12:58 shutdown_func -->
2012-05-16 10:12:58 start -->
2012-05-16 10:13:08 shutdown_func -->
2012-05-16 10:13:08 start -->
2012-05-16 10:13:18 shutdown_func -->
2012-05-16 10:13:18 start -->
2012-05-16 10:13:28 shutdown_func -->
2012-05-16 10:13:28 start -->
2012-05-16 10:13:40 shutdown_func -->
2012-05-16 10:13:40 start -->
2012-05-16 10:13:50 shutdown_func -->
2012-05-16 10:13:50 start -->
2012-05-16 10:14:02 shutdown_func -->
2012-05-16 10:14:02 start -->
2012-05-16 10:14:14 shutdown_func -->
2012-05-16 10:14:14 start -->
2012-05-16 10:14:26 shutdown_func -->
2012-05-16 10:14:26 start -->
2012-05-16 10:14:36 shutdown_func -->
2012-05-16 10:14:36 start -->
2012-05-16 10:14:48 shutdown_func -->
2012-05-16 10:14:48 start -->
2012-05-16 10:14:58 shutdown_func -->
2012-05-16 10:14:58 start -->
2012-05-16 10:15:08 shutdown_func -->
2012-05-16 10:15:08 start -->
2012-05-16 10:15:18 shutdown_func -->
2012-05-16 10:15:18 start -->

php_errors.log

[16-May-2012 02:11:54 UTC] PHP Fatal error:  Maximum execution time of 10 seconds exceeded in E:\eclipse_php_workspace\caijiche_new2\t.php on line 41
[16-May-2012 02:12:04 UTC] PHP Fatal error:  Maximum execution time of 10 seconds exceeded in E:\eclipse_php_workspace\caijiche_new2\t.php on line 41
[16-May-2012 02:12:14 UTC] PHP Fatal error:  Maximum execution time of 10 seconds exceeded in E:\eclipse_php_workspace\caijiche_new2\t.php on line 41
[16-May-2012 02:12:26 UTC] PHP Fatal error:  Maximum execution time of 10 seconds exceeded in E:\eclipse_php_workspace\caijiche_new2\t.php on line 41
[16-May-2012 02:12:38 UTC] PHP Fatal error:  Maximum execution time of 10 seconds exceeded in E:\eclipse_php_workspace\caijiche_new2\t.php on line 41
[16-May-2012 02:12:48 UTC] PHP Fatal error:  Maximum execution time of 10 seconds exceeded in E:\eclipse_php_workspace\caijiche_new2\t.php on line 41
[16-May-2012 02:12:58 UTC] PHP Fatal error:  Maximum execution time of 10 seconds exceeded in E:\eclipse_php_workspace\caijiche_new2\t.php on line 41
[16-May-2012 02:13:08 UTC] PHP Fatal error:  Maximum execution time of 10 seconds exceeded in E:\eclipse_php_workspace\caijiche_new2\t.php on line 41
[16-May-2012 02:13:18 UTC] PHP Fatal error:  Maximum execution time of 10 seconds exceeded in E:\eclipse_php_workspace\caijiche_new2\t.php on line 41
[16-May-2012 02:13:28 UTC] PHP Fatal error:  Maximum execution time of 10 seconds exceeded in E:\eclipse_php_workspace\caijiche_new2\t.php on line 41
[16-May-2012 02:13:40 UTC] PHP Fatal error:  Maximum execution time of 10 seconds exceeded in E:\eclipse_php_workspace\caijiche_new2\t.php on line 41
[16-May-2012 02:13:50 UTC] PHP Fatal error:  Maximum execution time of 10 seconds exceeded in E:\eclipse_php_workspace\caijiche_new2\t.php on line 41
[16-May-2012 02:14:02 UTC] PHP Fatal error:  Maximum execution time of 10 seconds exceeded in E:\eclipse_php_workspace\caijiche_new2\t.php on line 41
[16-May-2012 02:14:14 UTC] PHP Fatal error:  Maximum execution time of 10 seconds exceeded in E:\eclipse_php_workspace\caijiche_new2\t.php on line 41
[16-May-2012 02:14:26 UTC] PHP Fatal error:  Maximum execution time of 10 seconds exceeded in E:\eclipse_php_workspace\caijiche_new2\t.php on line 41
[16-May-2012 02:14:36 UTC] PHP Fatal error:  Maximum execution time of 10 seconds exceeded in E:\eclipse_php_workspace\caijiche_new2\t.php on line 41
[16-May-2012 02:14:48 UTC] PHP Fatal error:  Maximum execution time of 10 seconds exceeded in E:\eclipse_php_workspace\caijiche_new2\t.php on line 41
[16-May-2012 02:14:58 UTC] PHP Fatal error:  Maximum execution time of 10 seconds exceeded in E:\eclipse_php_workspace\caijiche_new2\t.php on line 41
[16-May-2012 02:15:08 UTC] PHP Fatal error:  Maximum execution time of 10 seconds exceeded in E:\eclipse_php_workspace\caijiche_new2\t.php on line 41
[16-May-2012 02:15:18 UTC] PHP Fatal error:  Maximum execution time of 10 seconds exceeded in E:\eclipse_php_workspace\caijiche_new2\t.php on line 41
[16-May-2012 02:15:28 UTC] PHP Fatal error:  Maximum execution time of 10 seconds exceeded in E:\eclipse_php_workspace\caijiche_new2\t.php on line 41
[16-May-2012 02:15:28 UTC] PHP Fatal error:  Maximum execution time of 10 seconds exceeded in E:\eclipse_php_workspace\caijiche_new2\t.php on line 33

シャットダウン関数が約 22 回呼び出され、突然呼び出されなかったようです。

私のPHPバージョンは5.3.9で、サーバーはIIS 7.5です 本当に助けが必要です! どうもありがとう!

-----------------------更新1------------------------- -------------------

掘り下げた後、phpソースにテストスクリプトが見つかりました。登録されたシャットダウン機能がタイムアウトする可能性があるようです。

<?php
set_time_limit(1);
register_shutdown_function("plop");

function plop() {
    $ts = time();
    while(true) {
        if ((time()-$ts) > 2) {
            echo "Failed!";
            break;
        }
    }
}
plop();
?>

結果は次のとおりです。

Fatal error: Maximum execution time of 1 second exceeded in E:\eclipse_php_workspace\caijiche_new2\t.php on line 9

Fatal error: Maximum execution time of 1 second exceeded in E:\eclipse_php_workspace\caijiche_new2\t.php on line 9
4

1 に答える 1

0

開始から終了まで 12 秒かかり (zz.txt のタイマーを参照)、最大実行時間は 10 秒に設定されています。問題があります。

通常、制限時間のカットオフを (max-execution-time - 5 秒) に設定しますが、10 秒と 2 秒のオーバーレイしかないため、シャットダウンを 7 秒に設定する必要があります。


これをブラウザから起動する場合は、META Refresh 命令から実際に「自分自身を呼び出す」ことを優先する場合があります。このようにして、小さな HTML ページを発行して、ステータスとメタ リフレッシュをそれ自体に戻すことができます。(これも私の好みのルートです!) ブラウザ以外から cron やその他のバックエンド プロセスを実行している場合は無視してください。


「現在停止していますが、数分後に戻ってきます」に応じて編集します(コメントの入力を節約するため)。

私が推測しているのは、まだ PHP スクリプトが自分自身を呼び出している場合、それはおそらくますます多くのメモリを消費しており、iteslf がガベージ コレクションを実行することを決して許可していません。Apache の各 PHP スクリプトは、約 10MB の Apache オーバーヘッドに加えて、さらに 2 ~ 3MB の PHP スクリプトを必要とします。

したがって、提案の1つに戻る必要があります。

a) ブラウザから呼び出す場合は、PHP 自体を呼び出すのではなく、

<html>
   <head>
      <meta http-equiv="refresh" content="1; url=http://127.0.0.1/t.php">
   </head>
   <body>
     Echo going to <a href="http://127.0.0.1/t.php">http://127.0.0.1/t.php</a>
   </body>
</html>

これは、PHP スクリプトで自分自身を呼び出していることを意味します。PHP も息を吹き返し、ガベージ コレクションを行うことができますが、単純なスクリプトを 1 つ実行するだけでは中断は必要ありません。

問題: 接続が失敗した場合、またはインターネットが失敗した場合、応答が発生せず、スクリプトが壊れます。

b) これのバリエーションとして、10 秒ごとにサーバーを呼び出す JavaScript を少し作成します。Javascript はプロセスを再開するだけなので、タイムアウト後は何もしないでください。

c) ただし、これを「永久に」実行したい場合は、cron ジョブからコマンドライン (php -q /var/www/html/Myphp.php > /dev/nul) として PHP スクリプトを実行するのが最善の方法です。cron ジョブを毎分実行するように設定します。自分自身を呼び出すたびにインクリメントし、6 回目の呼び出し (つまり 1 分) 後に停止するカウンターをスクリプトに追加します。このようにして、スクリプトが停止し、それ自体をクリーンアップできるようにする前に、最大 5 回ループします。

d) または、簡単なシェル スクリプトを作成できる場合は、PHP コマンド ラインを呼び出してから 10 秒待ってから再度呼び出すシェル スクリプトを 6 回作成します。毎分実行される cron からそのスクリプトをトリガーします。この方法では、Apache のオーバーヘッドがなく (ソケットを節約し、メモリを節約できます)、ロッピングの問題を回避できます。

e)他のバリエーションがあります-サーバーで持っている権限に応じて...

彼らがあなたの問題を解決するとは約束していませんが、自分自身を際限なく呼び出す関数はノーノーをプログラミングしているので、少なくとも最初の1つを突き刺して、それが機能するかどうかを確認してから、より複雑なものを調査します.

于 2012-05-16T04:30:46.343 に答える