• ベストアンサー

タイムアウト処理?となる

ローカルのシステムでデータベースからCSVファイルを作成して、公開用WEBサーバへFTPアップロード。その後CSVファイルをWEB用データベースに登録する処理を開発しているんのですが、開発用WEBサーバでは正常に完了するのですが、本番用WEBサーバで行うと最初の数万件は登録できているのですが、途中でエラーというか真っ白になって処理がSTOPしてしまいます。 開発、本番用共に同じPHPのファイルを使用しており、データベース構成も同じです。 【相違点】 開発(正常):PHP4.4.2(Apacheモジュールにて動作) 本番(異常):PHP4.4.1(CGI動作) エラーとなるのも、CSVのファイルの容量によって違います。 ちなみにFTPでのアップロードは開発・運用供正常にできています。 どなたかご教授お願いします。

  • S202
  • お礼率84% (142/169)
  • PHP
  • 回答数5
  • ありがとう数4

質問者が選んだベストアンサー

  • ベストアンサー
  • galluda
  • ベストアンサー率35% (440/1242)
回答No.4

がるです。 んと…ちと長くなりますのでご覚悟を(笑 #2さんのおっしゃっている「メモリ」問題の可能性も考えてはいるのですが、今回の件はいわゆる「タイムアウト系かなぁ」お思ってますので、その観点から。 まず「htaccessでは」とのお話しですが…すみませんちょっとこのあたりは。 Timeoutディレクティブなのは把握しているのですが…元々、普段は .htaccess自体を、性能の観点からoffにしているので、あまり詳しくなくて。 もし設定される場合、例えば Timeout 7200 とかにしておくと、大分よいかと思います。数値の単位は秒です(通常、最近は300が多いのですが…レンタルサーバですと30とかで切ってるかもしれません)。 ただ、.htaccessでTimeoutディレクティブが有効になるかどうかはちとわからないです。 > 10000件ごとに取り込み状況を出力するように変更したのですが、的を外れていますか? 残念ながら。 ちと厳密に書くと。 Apacheのプロセスは、CGI(今回ですとPHPプログラム)を起動します。で、そのプログラムのstdout(標準出力)が完全にcloseし、プログラムが終了した時点で初めて出力を行うのが通常なので。 結局のところ、プログラムが動いている最中は、今まで試した限りでは、「別プロセスにforkした場合」を含め、すべてNGでした。 ですので、ある程度以上の作業であれば、どうしても「裏側で別途処理」という流れになることが多いです。 なので、cronで、という流れになるのですが。 あとは…行数制限をかけてしまうのが、恐らくは現実解なのではないか、と思います。 あまり役に立つ情報でなく大変に恐縮ですが。

S202
質問者

お礼

お礼が遅くなってしまい申し訳ありませんでした。 アドバイスありがとうございました。 Timeoutディレクティブは.htaccessでは無理でした。 結局、抽出する件数を指定してFTPアップロード→WEBサーバ側で取込後 また抽出といった処理に変更しました。 この方法だと、処理に時間がかかりますが正常に動作しました。 同時にWEBサーバの容量の問題も解決できました。

その他の回答 (4)

  • NINJA104
  • ベストアンサー率43% (133/306)
回答No.5

#2です。 error_logはapacheのerror_logではなくて、phpのerror_logの事だったのですが、設定されていないとの事なので情報は得られないとの事了解致しました。 #1氏がforkで駄目だった経験がお有りとの事で、これから私が説明する手法ーもforkの様なものなのでやはり駄目かもしれませんが一つ。 (尚、今思い付いたので検証はしておりません) CSVを読み込んでDBに保存するスクリプトを処理単位で3分割します。 a.ブラウザから処理開始のトリガーを引く為だけのスクリプト。 b.単純にCSVを読み込んでDBを更新するだけのスクリプト。 c.bの処理が終了しているかどうかを確認するだけのスクリプト。 まず、ブラウザからaが呼び出されたら、まずは処理開始のフラグを立てます。(ファイルでも良いし、DBに専用のテーブルを用意しても良い) 続けて system() を使ってbを呼び出しますが、その際のパラメータストリングの末尾に "&" を付けます。 具体的には system("/usr/bin/php -q bのスクリプトパス &"); とします。 これでbは常駐扱いとされて直ぐに処理が戻ってくる筈なので、取り合えずブラウザには「更新処理中です」等と出力して終了します。 bは処理が終わったらaが立てた処理中フラグを降ろします。 cは呼び出される都度にaが立てた処理中フラグを確認し、立っていれば「処理中です」と出力して終了。降りていれば「完了しました」を出力して終了します。 このcをaの処理が終わった時に出力されるHTMLのヘッダにmetaタグのrefresh定義を利用して10秒程度の間隔で何度も呼び出す様にします。 c自信も結果を出力する際に、まだフラグが立っていたら同じくmetaタグを仕込みます。(つまり自分を再度呼び出す様に仕掛けます) 頭の中ではイケそうな気もしますが、いかんせん検証していませんので駄目元という事で簡便してください。

S202
質問者

お礼

アドバイスどうもありがとうございました。 結果的に無事動作するようになりました。 NINJA104さんの処理については今後の参考にさせていただきます。

  • galluda
  • ベストアンサー率35% (440/1242)
回答No.3

がるです。 なるほど状況は概ね。 PHPでどれだけの設定をしようとも、最終的には「Apacheの設定次第で切られてしまう」というのが、この場合直接的な回答になろうかと思います。 もうちょっと詳細に書くと。 「CSVを処理している最中にApacheの設定している接続時間を超えた場合にその時点で"処理が片付かない"エラーでApache自身が異常終了として処理してしまう」ため。またファイルサイズによって違うのは「ファイルサイズによってCSV処理時間が異なるため」になります。 Apacheの、通常httpd.confと呼ばれる設定ファイルの中に、接続時間への設定などがあるので。 で、解決策ですが。 httpd.confの設定を長くするのが一つ。下策ですがとりあえず楽ですが、やはりどこかで同じ事象に悩まされます。 CSVファイルが「一定サイズ以上にならない」のであればある程度逃げれるのですが。 上策は「つくりを変える」事。具体的には ・CSVのupload ・CSVの処理 を別々に行います。CSVの処理は、cronあたりでバッチにするほうがよろしいかと。 この方法の場合、どんだけのファイルサイズがあろうとも、基本的には問題なく動きます。 ただ、画面遷移など色々変更がはいるでしょうから、多分大変です。 何かの参考にでもなれば幸いです。

S202
質問者

お礼

がるさんアドバイスありがとうございます。 Apacheの設定ですが、htaccessではできない項目なんでしょうか? あと処理の流れはローカルのシステム内でCSV生成後FTPアップロード。 そのあとheader関数でWEBサーバ内のCSV取り込み処理のファイルへアクセス。 そのまま取り込みを行っています。 がるさんが言われている「つくりを変える」と言う内容はこういうことではダメということでしょうか? cronのバッチ処理は公開用のサーバが対応していません。 いろいろと調べまして、10000件ごとに取り込み状況を出力するように変更したのですが、的を外れていますか? 確かIEの接続時間の関係でこういう処理をすればタイムアウトにならないという情報が検索して見つかったので試してみました。 開発用では200万件のデータの取り込みは正常にできました。 ちなみに開発用のWEBサーバもレンタルサーバです。 もし、ご回答いただければ嬉しいです。

  • NINJA104
  • ベストアンサー率43% (133/306)
回答No.2

error_logには何が出力されていますか? 私の経験ではメモリが足りなくなった場合に、ブラウザに同じ挙動(真っ白)が返った時がありました。 その場合、php.iniの利用するメモリ上限値設定を見直して余裕を持たせるか、またはメモリを無駄に消費しない様にコードを自力で最適化(必要ではなくなった変数をせっせとunset()する等)して対策を取るかのどちらかですね。

S202
質問者

補足

apacheのerror_logには 「Premature end of script headers:ファイル名・・・」 とありました。 調べてみたのですが、どこかにエラーがありますとしかわかりませんでした。 ちなみに本番用はレンタルサーバになります。 memory_limitは本番、開発共に同じ値(項目なし)です。 CGI版とApacheモジュール版ってちがうのでしょうか?

  • galluda
  • ベストアンサー率35% (440/1242)
回答No.1

がると申します。 拝見している限りですと「処理に時間が掛かっているから途中でタイムアウトしている」、ごく普通というか真っ当な挙動だと思うのですが。 ご質問は「タイムアウトしないためには」でよろしいでしょうか?

S202
質問者

補足

すいません。 説明不足でした。 set_time_limit(0);を指定しています。 にも関わらず本番環境及び開発環境(CGI動作)では 途中で止まってしまいます。

関連するQ&A

  • WCFでタイムアウトの延長

    VS2013でIISを使用してクライアント、サーバーと分けて運用しております。 クライアントからサーバーに処理を投げて1分たつとエラーになってしまいます。 タイムアウトを延長する方法を試したのですが、開発の環境ではうまく延長されたのに、本番の環境では延長されない現象がはっせいしています。 開発環境と本番の違いはロードバランサーがついているかいないかです。 開発は単体で本番は2筐体をロードバランサーで管理しています。 なにかヒントでもいいのでご教示頂ければ幸いです。 やったこと クライアントのapp.configに下記追加しビルド→発行 <bindings> <basicHttpBinding> <binding name="HttpSysBinding" maxBufferPoolSize="1073741824" maxBufferSize="1073741824" maxReceivedMessageSize="1073741824" openTimeout="00:10:00" closeTimeout="00:10:00" sendTimeout="00:10:00" receiveTimeout="00:10:00"> <readerQuotas maxStringContentLength="891200" /> </binding> </basicHttpBinding> </bindings> サーバー Web.configに下記追加 <system.transactions> <defaultSettings timeout="00:10:00"/>

  • DBを実装したサイトの制作手順について

    ローカルでDB(MySQL)+ Apache + PHPで制作したサイトを実際のウェブサーバーで動作させる場合、 phpファイル、htmlファイル、画像ファイル等は、 FTPでファイルを送りますが、 データベースは、どうするのですか?

    • ベストアンサー
    • MySQL
  • サーブレット処理のキャンセル

    はじめまして。 環境: apache2.052 + jk2(2.04) + tomcat5.028 質問: CSVファイルをアップロードして、DBに登録する業務があります。 CSVアップロード ↓ サーブレット:DB登録 ↓ 結果出力 DB登録の処理時間が20秒ほどかかるため、その間にブラウザを閉じたり、別のリンクをクリックされる場合があります(キャンセルの意を込めて?)。 そのような操作がされた場合、ユーザには登録の結果(エラーの有無等)を知る手段がないため、サーバ側のDB登録処理をキャンセル(ロールバック)させたいのですが、現状、ブラウザの状態にかかわらずDB登録処理は最後まで行われてしまいます。 なにかよい方法はございませんでしょうか。 また、一般的にはこのような処理は行わないものなのでしょうか。 よろしくお願いいたします。

    • ベストアンサー
    • Java
  • キャプチャ画像など静止画(jpg)を一定周期でFTPサーバーにアップロ

    キャプチャ画像など静止画(jpg)を一定周期でFTPサーバーにアップロードする方法 現在、Webカメラで取得したキャプチャ画像(.jpg)を一定周期でFTPサーバーにアップロードすることを検討しています。 その際、一定周期で行いために、 <form action="hoge.php" method="post" enctype="multipart/form-data"> <input type="submit" name="hoge" valuei="登録"> </form> のようにした場合、"登録"ボタンを押さなければならないような マニュアル動作が介在してしまい、本来意図した動作と異なってしまいます。。 現在、私がやりたいことは上記動作にて"登録"を押さなくても 一定周期にUploadを行い、Web上の表示に反映させたいと考えています。 もちろん、PCでの格納Directory及びファイル名に関してはある場所、あるファイル名で固定で構いません。 このように、Webカメラでキャプチャした画面を自動的にFTPサーバーへアップロードするために、PHPでどのように記載すればよろしいのでしょうか? 以上、よろしくお願いします。

  • PHPの設定 エラー処理について

    当方PHPの初心者です。 現在HTML上でPHPの動作をさせているのですが 一部の処理で【Fatal error: Call to undefined function】というエラーがでて処理が途中で止まってしまいます。 エラー文自体は正しく、元々テスト環境でPHPを動作させているので、本番のDBや該当ファイルが無い為にエラーとなっています。 ただ、ステージングという扱いにしてソースをそのままでアップさせたいので、エラーが必ず出る箇所を無視して先に進めたいと考えています。 エラーが起こる部分をコメントアウトする事は二度手間になり、本番化の場合にヒューマンエラーが発生するのを防ぐ為です。 そこでご相談なのですが、PHP処理の時に該当ファイルが無い等のエラーを無視してそのまま続行する。 方法はありますでしょうか。 通常の処理は動作確認済みです。 <?php echo date('Y年m月d日'); ?>等 エラーが発生するのは下記のような場合です。 <?php e($this->renderElement("サーバーが違うので存在しない")); ?> 色々情報を探ったのですが中々解決策をつかめず・・ どなたかお力添えを頂ければありがたいです。

    • 締切済み
    • PHP
  • WEBアプリケーションのタイムアウトについて

    ブラウザ<-回線->WEBサーバ(apache)<-回線->APサーバ(tomcat)<-回線->DBサーバ という並びの一般的なWEBアプリケーション(それぞれ物理的に別サーバです)において、 システム要件として下記を考慮をしなければならず、困っています。 1.データベースの処理時間が長い場合、 ブラウザ<-回線->WEBサーバの接続は何を基準に保たれるのでしょうか。 また、その時間はコントロール可能でしょうか。 2.データベースの処理時間が長い場合、 APサーバ(tomcat)<-回線->DBサーバの接続は何を基準に保たれるのでしょうか。 また、その時間はコントロール可能でしょうか。 3.APサーバの処理が長い場合、 WEBサーバ(apache)<-回線->APサーバ(tomcat) の接続時間は何を基準に保たれるのでしょうか。 また、コントールは可能でしょうか。 ご教授よろしくお願いします。

  • フリーのショッピングカート PHPスクリプトについて

    フリーのPHPスクリプト「ショッピングカート WebCart 2.31」を設置し動作確認したところアップロード機能がうまく動作しません。 以下の環境にて動作確認しております。 何がいけないのでしょうか? お手数をお掛けいたしますが、どなたかご教示お願い致します。 ローカルマシンOS:Windows VISTA BASIC サーバー環境:Linux 5.1 PHPスクリプト:ショッピングカート WebCart 2.31 http://www.cgis.biz/script_web_cart/ 上記スクリプトには全く手を加えず、FFFTPにてサーバーへアップし 各ファイルのパーミッションを設定しました。 IE/Firefoxにて商品登録をして、一覧表示など正常に動作しておりました。 ダウンロードメニューより商品設定(登録商品データー)を一旦ダウンロードして アップロードメニューより商品設定(登録商品データー)を何も手を加えず アップロードし、商品一覧を見たところ文字化けし、編集/削除しようにも 「Error: Bad Operation 3」と表示されてしまい、見ることが出来ません。 どうしたら正常にアップロードできるのでしょうか? CSVの回覧にはExcel2003とCassavaを使用しています。 以上、ご回答をお待ちしております。 宜しくお願い致します。

    • ベストアンサー
    • PHP
  • FTPでタイムアウトになる

    RedHatLinuxのサーバ間でFTP転送しようとしています。 例えばAとBとCというサーバがあったとします。 OSは全てRedHatLinuxでAとBは7.1、Cは7.3です。 FTPサーバは全てwu-ftpdです。 FTPコマンドで接続し、putで転送しようとしていて、BからAへの転送は正常にできます。 CからAに行おうとすると、接続は問題無いのですが、ファイル転送の際、数分後に「Connection Timed out」と出てしまい転送できません。 CからBに転送しようとしても同様のエラーでできませんでした。 ちなみにAとB及びCの間にファイアウォールが設定されていますが、BからもCからも通す設定にしていますし、 接続が正常にできるのでこれは問題ないと思うのです。BとCの間にはありません。 アクセス制限によるものかと思いましたが、特に制限していないですし、 一応ftphosts、tpusers、ftpgroupsやhosts.allow、hosts,denyファイルを確認してみたのですが、特に これと思われるものがありませんでした。 転送するファイルのアクセス権限を色々いじってたので、これが原因かとも思いましたが、 BからAに転送したものと同様に変更してみましたが、ダメでした。 何が原因なのでしょうか。

  • phpの互換性について

    phpの4.3.10と4.4.0ではどの程度の互換性があるのでしょうか? 現状、php4.4.0にて開発を行っていましたが、本番サーバのphpが4.3.10なのです 特に難しいこともしていないと思うので、動きそうな気はするのですが この関数の仕様が変わった。とか、こういう処理をすると動かないなどありますでしょうか? WebからDBに登録、変更などを行うありふれたツールです 画面表示にSmarty2.6.18を使用しています

    • ベストアンサー
    • PHP
  • GetFtpConnection(~)がタイムアウトしてしまいます。

    GetFtpConnection(~)がタイムアウトしてしまいます。 C++のプログラム操作から、FTPを利用してサーバ上のファイルをダウンロードする処理を構築中です。 とりあえずの練習用にと「AnHTTPD」を導入しました。 VisualStudioのWin32コンソールアプリケーションから、GetFtpConnectionで自家サーバに接続しようとしたところ、関数の処理内で先に進まなくなってしまい、そのうちに「処理がタイムアウトになりました」というメッセージボックスがあらわれます。元々20秒だったタイムアウトの設定を60秒にしてみましたが結果は変わらず、接続に時間がかかっているだけだというわけでもないようです。 ひょっとすると、ネット上に存在するFTPサーバに対する接続を、ローカルで行おうとしていることから起きている問題なのかもとは思うものの、それが正しいのか、正しいとしてどうすれば良いのかまったく見当もつかないでいます。 以下、FTPダウンロード検証用に試作中の・・・というのもお恥ずかしいプログラムです。 まったくのゼロからの開発中ですので、問題点の指摘や改善へのご指南を、どうかひとつお願いいたします。 //////////////////////////////////////////// #include <afxinet.h> int main() { CFtpConnection *pConn = NULL; char *lpszServerName = "210.250.71.132"; //CInternetSessionのインスタンス作成 CInternetSession session( "My FTP Session" ); //CFtpConnectionオブジェクトの作成 try { pConn = session.GetFtpConnection( lpszServerName,0,0,0, TRUE ); } catch( CInternetException *ep ) {//エラー ep->ReportError(); ep->Delete(); } //取得 char *pstrRemoteFile = "C\\homepage\\test"; char *pstrLocalFile = "C\\TEST_DL.txt"; if( !pConn->GetFile( pstrRemoteFile, pstrLocalFile, FALSE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_BINARY, 1 ) ) { MessageBox( NULL, "ファイルの取得に失敗", "FPS_GetFile", MB_OK|MB_ICONHAND ); } pConn->Close(); session.Close(); return 0; } //////////////////////////////////////////

専門家に質問してみよう