- ベストアンサー
タイムアウト問題によるサーバー処理の困難
- 一日のログ数が10万を超えた辺りから集計処理がタイムアウトしてしまい、集計ができなくなってしまいました。
- ループを多用して重い処理になっているため、タイムアウトせずに動かす方法を模索しています。
- 現在の環境で応急処置を行いたいが、タイムアウト時にはエラーメッセージが表示されず、ページが表示されなくなってしまっています。
- みんなの回答 (6)
- 専門家の回答
質問者が選んだベストアンサー
execの使い方は合ってますが、どうやら制限によって難しそうですね。 そこまで制限してるならサーバー移行が良いかも知れません。 と言いつつ、一つ思いついたので書いておきます。 「実行時刻(時)の2時間前~1時間前のログのみを対象として集計する」というスクリプトを1時間に1回実行します。 2010/2/20 0:00~1:00のログは同日2時に集計 2010/2/20 1:00~2:00のログは同日3時に集計・・・ 保存先のDBでそのような分割実行でも集計できるテーブルになってる必要がありますが、計算量は24分の1になるはずなのでしばらくは大丈夫だと思います。 #実際には引数でいつの分を集計するか指定できたほうが良いですが
その他の回答 (5)
- bm_hiro
- ベストアンサー率51% (200/388)
解決策でもなく回避策でもなく、 俺なら こうするかなって言う妄想レベルの話ですので、聞き流しでお願いします。 ローカルにXAMPP入れて、ローカルからネット上にデータを取りに行って、集計したら、ネット上に戻してやる感じでやれば、多分 タイムアウトしません。 ただ、データの量的に なんか問題がある気もします。 ちなみに、俺は 最初に自分でブラウザからトリガー引いた後は、8時間以上 放置して、データをネットから自動で拾い続けさせていた事があります。
お礼
いろいろと策をお考え頂きまして有難うございました。 ANo,5のお礼に記載させて頂いた方法にて、処理を完了するところまで持っていくことができました。 XAMPPは一度触ったことがある程度でbm_hiro様の様に、難しい連動をさせるのには、知識不足かもしれません。。 本当にいろいろとお力をお貸し頂きまして、感謝しております。 有難うございました!
CLI版のPHPは「/usr/bin/php5cli」で利用することが出来そうです。 しかし、CORESERVERではジョブの最大実行時間が3分間に制限されているようで、これはCGI版やモジュール版の300秒よりさらに短い設定値ですね。 CLI版のPHP自体は「max_execution_time」が0で無制限となりますが、制限により3分で強制終了するのであれば、CLI版であってもタイムアウトしてしまいますので、当方のアドバイスは無意味でした。この線は捨ててください。
お礼
わざわざお調べ頂きまして、有難うございました。 このような負荷制限があると、やはりサーバを移した方が賢明なのでしょうか…。 サーバー移行も含めて、いろいろと考えてみることにします。 有難うございました!
- yuuki0229
- ベストアンサー率70% (33/47)
Apache側のタイムアウト設定に依存してそうです。 Web上でやる場合、 exec("/usr/bin/php heavy_script.php > /dev/null 2>&1 &"); のようにバックグラウンドでスクリプトを実行すればひとまずApacheのタイムアウトは気にしなくてよくなります。 そして1日1回実行とのことですが手動でしょうか? Cronから1日1回、PHPを実行すれば元々Apache関係なく処理できます。 ループのアルゴリズムに無駄があるかどうかは挙げられたコードでは判断できませんでした。
お礼
ご回答有難うございます。 exec関数について、使ったことがないので調べてみましたが、使い方が今ひとつ掴めません。 重い処理のスクリプト(c_batch.php)を、同じ階層に作成したexec.phpを頂いたご回答を元に下記のように記載し、exec.phpへブラウザからアクセスしたのですが、処理がされていない様です。。 ↓exec.php <?php echo exec("/usr/bin/php ".dirname(__FILE__)."c_batch.php > /dev/null 2>&1 &"); ?> 勉強不足の為、ご回答頂いた内容と全く違うことをしているかもしれません。 その際は申し訳ありません。 また、cornから…という処理方法が本来行いたい方法でした。 しかし、$iの処理回数が74回あるうち、58回終了後、処理がとまってしまってしまい、処理が中途半端で終わってしまってしまうのです。。 Apachのタイムアウトが関係ないとなると、他の原因はどのようなことが考えられますでしょうか? できれば、cornにて午前4時頃に自動で処理を完了させてしまいたいので、重ねてのご質問になってしまい申し訳ありませんが、お力をお貸し頂ければと思います。 exec関数に関しては、理解が浅い状況ですので、引き続き理解を深めるよう勉強していきたいと思っております。 アドバイス有難うございました。
- bm_hiro
- ベストアンサー率51% (200/388)
環境が違うので参考にならないかもしれませんが、一応 そちらと同じ方法でタイムアウト防止させていて、1~2時間程度なら 問題なく動いてます。 それ以上、時間のかかることをしたことがないだけで、それ以上でも動くものと思われます。 ただ、俺の環境はXAMPPでローカルの自分のPCの中にあるテキストファイルを読み出して、解析して、DBに叩き込むだけなので、負荷は常識の範囲内だと思います。 なので、参考にはならないかもしれません。 俺も どっかから コピペしてきた奴なんですけど、そちらと同じようにして使ってます。 // タイムアウト防止処理 set_time_limit(0); // 実行時間を制限しない ob_end_clean(); // 出力をバッファリングしない(==日本語自動変換もしない) print str_pad('',256); // IEのために256バイト空文字出力 ただ、他にも 超うろ覚えで 別のと記憶違いしてる気がしないでもないんですけど、 php.ini とか httpd.conf も いじったような気もします。 ほんと、役に立たない回答で すみません。
お礼
有難うございます。 おそらく環境の違いか何かでタイムアウトする時間が違うのかもしれません。 解決に向けて頑張ってみます。 有難うございました。
おそらくCGI版と同じ場所に、CLI版のPHPが用意されています。バッチ処理にはこれを利用すると便利です。 ロジックの見直しなどは、ローカルで行うことをお勧めします。
お礼
有難うございます。 CLI版のPHPの導入をできるよう勉強してみます。 正直CLI版を簡単に導入して、処理を復旧できるレベルではなさそうですが…。
お礼
execの件、確認頂きまして有難うございました。 その後いろいろと試行錯誤し、毎時間cornから処理プログラムを起動させ、一度タイムアウトまで処理を行い、1時間後はタイムアウトまでに処理されたログの集計を飛ばして、続きから処理させるようにしました。 毎時間、途中から集計処理をさせることで、全ての処理を完了するところまでいくことができました。 体感で15~30分でタイムアウトになってしまうようですので、前日の処理は日が昇る前には完了することができ、一応理想としていた処理の形とすることができました。 ただし、処理完了後も同じ処理が毎時間走ってしまいますので、集計処理用のログテーブルを作成し、前日の処理が終了したら集計処理完了ログを作成し、完了ログがあった場合は処理を中止するという仕組みにすれば、サーバーへの負荷も軽減できると思いますので、構築しようと思っております。 正直cornも正常に走っているか、深く追求しておりませんでしたので、cornを追求するきっかけを与えて頂いたyuuki0229様に感謝しております。 linuxでのサーバー構築を前倒しにして、自前サーバーにて安定した運用ができるようにしていきたいと思っております。 linuxの方もいろいろと勉強する点が多々ありますが、いろいろとお知恵をお貸し頂きまして有難うございました。