1

オンライン ゲームの個々のプレーヤーのデータを追跡する Web サイトがあります。毎日同時に、cURL を使用してゲーム会社のサーバーから各プレイヤーのデータをフェッチする cron が実行されます (各プレイヤーは、フェッチするために独自のページを必要とします)。以前は、各プレーヤーをループして、一度に独自の cURL リクエストを作成し、データを保存していました。これは遅いプロセスでしたが、数週間はすべて正常に機能していました (毎日 500 から 1,000 プレーヤーのどこかで実行していました)。

プレイヤーが増えるにつれ、cron の実行に時間がかかりすぎたので、約 1 週間前にParallelCurl (cURL マルチ ハンドリング) を使用して書き直しました。一度に開く接続数は 10 以下に設定されており、完璧に動作していました。3 ~ 4 分で約 3,000 ページを処理していました。1 日か 2 日後、ランダムにサーバーに接続できなくなる (http コード 0 を返す) まで、何か問題があることに気づきませんでした。約1〜2時間後に突然再び接続できるようになるまで、私は永久に禁止/ブロックされたと思っていました. ブロックは、その日の cron が実行されてから数時間後に発生しました。その時点で行われていた唯一のリクエストは、時折行われていた単一のファイル リクエストでした (正常に機能し、何ヶ月も放置されていました)。

ここ数日はみんなこんな感じです。Cron は正常に動作しますが、その後 (数時間) 1 時間か 2 時間接続できません。今日、一度に 5 つの接続のみを開くように cron を更新しました。

私は大量のグーグル検索を行ってきましたが、有用なものが見つからないようです。おそらくファイアウォールが私の接続をブロックしていると思いますが、そのようなことになると本当に頭がいっぱいです. 何が起こっているのか、それを修正するために何をする必要があるのか​​ について、私は本当に無知です. 私はどんな助けにも感謝します - 推測でも、正しい方向への単なる指摘でも。

共有 Web ホスト (HostGator) を使用していることに注意してください。2 日前にチケットを送信し、フォーラムに投稿しました。また、会社に電子メールを送信しましたが、まだ返信がありません。

- 編集 -

これは、parallelcurl を使用して複数のリクエストを実行するコードです。インクルードはそのままにしてあり、ここに示されているものと同じです

set_time_limit(0);

require('path/to/parallelcurl.php');

$plyrs = array();//normally an array of all the players i need to update

function on_request_done($content, $url, $ch, $player) {
    $httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);    
    if ($httpcode !== 200) {
        echo 'Could Not Find '.$player.'<br />';
        return;
    } else {//player was found, store in db
        echo 'Updated '.$player.'<br />';
    }
}

$max_requests = 5;

$curl_options = array(
    CURLOPT_SSL_VERIFYPEER => FALSE,
    CURLOPT_SSL_VERIFYHOST => FALSE,
    CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.9) Gecko/20071025 Firefox/2.0.0.9',
);

$parallel_curl = new ParallelCurl($max_requests, $curl_options);

foreach ($plyrs as $p) {
    $search_url = "http://website.com/".urlencode($p);
    $parallel_curl->startRequest($search_url, 'on_request_done', $p);
usleep(300);//now that i think about it, does this actually do anything worthwhile positioned here?
}

$parallel_curl->finishAllRequests();

接続できるかどうかを単純に確認するために使用するコードは次のとおりです

$ch = curl_init();

$options = array(
    CURLOPT_URL            => $url,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HEADER         => true,
    CURLOPT_FOLLOWLOCATION => true,
    CURLOPT_ENCODING       => "",
    CURLOPT_AUTOREFERER    => true,
    CURLOPT_CONNECTTIMEOUT => 120,
    CURLOPT_TIMEOUT        => 120,
    CURLOPT_MAXREDIRS      => 10,
    CURLOPT_SSL_VERIFYPEER => false,
    CURLOPT_SSL_VERIFYHOST => false,
);
curl_setopt_array( $ch, $options );
$response = curl_exec($ch); 
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);

print_r(curl_getinfo($ch));

if ( $httpCode != 200 ){
    echo "Return code is {$httpCode} \n"
        .curl_error($ch);
} else {
    echo "<pre>".htmlspecialchars($response)."</pre>";
}

curl_close($ch);

接続できないときにそれを実行すると、次のようになります。

Array ( [url] => http://urlicantgetto.com/ [content_type] => [http_code] => 0 [header_size] => 0 [request_size] => 121 [filetime] => -1 [ssl_verify_result] => 0 [redirect_count] => 0 [total_time] => 30.073574 [namelookup_time] => 0.003384 [connect_time] => 0.025365 [pretransfer_time] => 0.025466 [size_upload] => 0 [size_download] => 0 [speed_download] => 0 [speed_upload] => 0 [download_content_length] => -1 [upload_content_length] => 0 [starttransfer_time] => 30.073523 [redirect_time] => 0 ) Return code is 0 Empty reply from server
4

1 に答える 1

1

これは、PHP/コードの問題ではなく、ネットワークまたはファイアウォールの問題のようです。

小さな DOS 攻撃と誤解される可能性のあるアウトバウンド トラフィックのスパイクがあるため、HostGator がアウトバウンド接続をブロックしているか、ゲーム Web サイトが同じ理由でブロックしています。特に、これはリクエストの数が増えてから始まったばかりです。また、0 の HTTP ステータス コードは、ファイアウォールの動作を示唆しています。

または、curl リクエストの後、後でその Web サイトを読み込もうとしたり、サーバーから開いている接続が多すぎるためにダウンロードできないファイルをダウンロードしたりすると、接続が適切に閉じられない可能性があります。

サーバーへの SSH アクセスがあれば、ネットワーク接続が開いている問題であればデバッグを手伝うことができるかもしれません。

別の解決策として、ゲーム Web サイトのスクレイピングを遅くして (リクエスト間の待機時間を導入する)、ネットワーク トラフィックが高いというフラグが立てられないようにすることも考えられます。

于 2013-05-24T09:32:51.257 に答える