2010-12-31 11 views
3

私の現在のコード(下記参照)は147MBの仮想メモリを使用しています! プロバイダがデフォルトで100MBを割り当てていて、処理が一旦終了すると内部エラーが発生します。 コードはcurl multiを使用しており、仮想メモリを最小限に抑えながら150回以上の反復でループできる必要があります。以下のコードは150回の反復でのみ設定され、依然として内部サーバーエラーが発生します。 90反復では、問題は発生しません。私のPHPコードを最適化して仮想メモリを減らすには?

リソースの使用/仮想メモリを削減するためにコードを調整するにはどうすればよいですか?

ありがとうございます!

<?php 

    function udate($format, $utimestamp = null) { 
     if ($utimestamp === null) 
     $utimestamp = microtime(true); 
     $timestamp = floor($utimestamp); 
     $milliseconds = round(($utimestamp - $timestamp) * 1000); 
     return date(preg_replace('`(?<!\\\\)u`', $milliseconds, $format), $timestamp); 
    } 

$url = 'https://www.testdomain.com/'; 
$curl_arr = array(); 
$master = curl_multi_init(); 

for($i=0; $i<150; $i++) 
{ 
    $curl_arr[$i] = curl_init(); 
    curl_setopt($curl_arr[$i], CURLOPT_URL, $url); 
    curl_setopt($curl_arr[$i], CURLOPT_RETURNTRANSFER, 1); 
    curl_setopt($curl_arr[$i], CURLOPT_SSL_VERIFYHOST, FALSE); 
    curl_setopt($curl_arr[$i], CURLOPT_SSL_VERIFYPEER, FALSE); 
    curl_multi_add_handle($master, $curl_arr[$i]); 
} 

do { 
    curl_multi_exec($master,$running); 
} while($running > 0); 

for($i=0; $i<150; $i++) 
{ 
    $results = curl_multi_getcontent ($curl_arr[$i]); 
    $results = explode("<br>", $results); 
     echo $results[0]; 
     echo "<br>"; 
     echo $results[1]; 
     echo "<br>"; 
     echo udate('H:i:s:u'); 
     echo "<br><br>"; 
     usleep(100000); 
} 

?> 
+0

@dqhendricks: "私のプロバイダはデフォルトで100MBを割り当てました" ==共有ホスティング。 – thirtydot

+0

@dqhendricks、@thirtydot:LinuxでWHMを使用する。私はサーバーの情報で私の質問を更新しました。私は、あなたがApacheよりもむしろコマンドラインでそれを実行することによって何を意味するのか分からないのですか?申し訳ありません.. – iCeR

+0

@iCeR:テストしているテストページは何バイトありますか? – thirtydot

答えて

0

150個のクエリそれぞれの結果がPHPメモリに格納されており、証拠によってこれは不十分です。唯一の結論は、150のクエリをメモリに保持できないことです。メモリバッファの代わりにファイルにストリーミングする方法、またはクエリの数を減らし、バッチでURLリストを処理する方法が必要です。あるコールバックで正しいファイルハンドルを取得

http://www.php.net/manual/en/function.curl-setopt.php#98491

function on_curl_write($ch, $data) 
{ 
    global $fh; 
    $bytes = fwrite ($fh, $data, strlen($data)); 
    return $bytes; 
} 

curl_setopt ($curl_arr[$i], CURLOPT_WRITEFUNCTION, 'on_curl_write'); 

:使用する

はあなたが0にCURLOPT_RETURNTRANSFERを設定し、CURLOPT_WRITEFUNCTIONのためのコールバックを実装する必要がありますストリーム、PHPマニュアルの例があります読者が解決するための問題として残した。あなたの最後のコメントを1として

+0

@ Steve-o:APIへのクエリでは、同じURLを150回以上実行しています。この理由は、継続的なチェックを行い、更新/変更を通知するためです。 APIは現時点ではかなり防げています。上記のコードをどのようにファイルに流すことができますか?クエリの数を減らすことは、バッチ処理で次の処理を行う方法がない限り、増加するものはありません。大変ありがとうございました。 – iCeR

+0

長さが814の150個のファイルはすべて1メガバイト未満です。私はファイルへのストリーミングがここで何か変わるとは思わない。 –

+0

@Billyこれは、CURLハンドルのクリアを除いて、ここで唯一制御可能な変数です。 –

0
<?php 

echo str_repeat(' ', 1024); //to make flush work 

$url = 'http://__________/'; 
$fetch_count = 15; 
$delay = 100000; //0.1 second 
//$delay = 1000000; //1 second 


$ch = curl_init(); 
curl_setopt($ch, CURLOPT_URL, $url); 
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); 
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); 


for ($i=0; $i<$fetch_count; $i++) { 

    $start = microtime(true); 

    $result = curl_exec($ch); 

    list($result0, $result1) = explode("<br>", $result); 
    echo "{$result0}<br>{$result1}<br>"; 
    flush(); 

    $end = microtime(true); 

    $sleeping = $delay - ($end - $start); 
    echo 'sleeping: ' . ($sleeping/1000000) . ' seconds<hr />'; 
    usleep($sleeping); 

} 

curl_close($ch); 

?> 
+0

@thirtydot:タイムスタンプを設定して、それを900msごとに出力します。/これをもっと速くする方法はありますか? – iCeR

+0

@iCeR:900msが費やされているところをプロファイルできますか?たとえば、 '$ result = file_get_contents($ url);を' $ start_get = microtime(true);に変更します。 $ result =ファイル_get_contents($ url); $ end_get = microtime(true); echo $ end_get - $ start_get; ' – thirtydot

+0

@thirtydot:$ urlの内容を取得するには、755msから932msの範囲です。それ以降はわずか9msです。 curl_multiを使うとurlを何度も読み込んで50ms以内に吐き出すことができるので奇妙です。 – iCeR

2

..

ダウンロードRollingCurl.php

これは、あなたのAPIからリビングの昼光を十分にスパムすることを望みます。

ご質問を通じて探し
<?php 

$url = '________'; 
$fetch_count = 150; 
$window_size = 5; 


require("RollingCurl.php"); 

function request_callback($response, $info, $request) { 
    list($result0, $result1) = explode("<br>", $response); 
    echo "{$result0}<br>{$result1}<br>"; 
    //print_r($info); 
    //print_r($request); 
    echo "<hr>"; 
} 


$urls = array_fill(0, $fetch_count, $url); 

$rc = new RollingCurl("request_callback"); 
$rc->window_size = $window_size; 
foreach ($urls as $url) { 
    $request = new RollingCurlRequest($url); 
    $rc->add($request); 
} 
$rc->execute(); 

?> 

、私はthis commentを見た:

意図がドメインひったくりであれば、 は、確立 サービスのいずれかを使用すると、より良いオプションです。 スクリプトの実装は、実際には と重要ではなく、待ち時間は です。

私はそのコメントに同意します。

https://stackoverflow.com/users/558865/icer
https://stackoverflow.com/users/516277/icer

How can I adjust the server to run my PHP script quicker?
How can I re-code my php script to run as quickly as possible?
How to run cURL once, checking domain availability in a loop? Help fixing code please

はまた、あなたは "同じ質問" 約700回を掲載しているように見えますHelp fixing php/api/curl code please
How to reduce virtual memory by optimising my PHP code?
Overlapping HTTPS requests?
Multiple https requests.. how to?

あなたが繰り返し同じ質問をし続けなければならないとオーバーyou're doing it wrongことを教えてくれているという事実をしないのですか?あなたの

This comment

@mario:乾杯。私は特定の 他の2社と競合しています ccTLD's。彼らはゲームの初心者であり、 は、 の時間が遅い( のパージ時間後に10秒まで)それらのドメインをスナップしています。私は今少し遅いです 現時点では。

私は、共有ホスティングアカウントのPHPは、間違いなく有効期限の切れたドメイン名のスナップで2社を打倒しようとしている場合、間違ったツールだと確信しています。

+0

私はあなたのコメントに完全に同意します。この種類のスクリプトのためにOPは専用またはVPSを取得する必要があります。 –

関連する問題