やっぱりscratchだろう。 IT会社社長のクリエイティブBlog

株式会社606代表取締役兼
有限会社豊工機システムソリューションズ代表取締役
豊知也のBlog。


テーマ:
どうも。


あーあー、


もう十二分に嫌になってきてますが、
またまたEC-CUBEです。
エラーが出た時、どうしても無理な時だけ助けてー!
という知り合いからの依頼なので断れず。
仕方が無いのでやってますが、、
色んな意味で開発の仕事やってる事自体嫌になって来ました。



さて、今回のアレですが、
17000商品ぐらい一気にCSVでアップしようとすると、Internal Server Errorが出ると。
PHPでしょ?EC-CUBEって。。
で、商品数を減らしてみると、アップできたり出来なかったり??
最終1商品まで減らしても、やっぱり同じのが出たりして??
何じゃそりゃ。

ちなみにサーバーは「sixcore」ってところの多分安いやつ。
EC-CUBEは2.12.2。

ってか、PHPだから、PHPがエラー吐いてほしいところ。どうなってるわけよ。
で、サーバー側のエラーログを見ると、こんな感じ。

mod_fcgid: read data timeout in 40 seconds, referer: http://xxxxx.com/admin/products/upload_csv.php
Premature end of script headers: upload_csv.php, referer: http://xxxxx.com/admin/products/upload_csv.php



先にmod_fcgidから。


これはFastCGIってやつのモジュールで、プロセスを破棄せず永続化再利用することで高速化しますよーってやつ。
一定数のアクセスが継続的にあるようなサイトで有効なんでしょうな。きっと。
で、こいつのタイムアウトが40秒になっとると。
なるほどね。
1行でもアップできなくなったのは、永続化したプロセスが動きっぱなしになって、プールしてるプロセスがいっぱいになってwaitかかったとか、もしくはメモリ食いつぶしちゃって云々か。。
まぁそんなところだろう。


ちなみに対策は、Apacheのhttpd.confを触れるなら


IPCCommTimeout 300


みたいに書いてやれば(これだと300秒)対応出来るんだけど、
どうやらこのサーバーはphp.iniは触れても、httpd.confはダメらしい。
ま、そりゃそうか。
仕方ないので、管理画面からFastCGI(PHP高速化設定って書いてある)を停止。
するとmod_fcgidのエラーは出なくなると。



で、もう一つPremature end of script headers の方。



これがやっかい。

基本的にこれがPHPで出るのは、
・拡張子.phpでCGI(perl)が動くようになっとる場合
・実行したphpのパーミッションで、グループなど(所有者以外)に書き込み権限がある場合

の2パターンらしい。
でも、EC-CUBEの他のページは動いてんだ。
だから、この2つは無い。


じゃぁ何?


調べると、PHPなどのtimeoutよりもApacheのタイムアウトが先に来ると、
こんなエラーが出るらしい。

参考:リクエスト処理時間が数時間? - HTTPサーバのタイムアウト設定について -

で、おんなじエラーが出てる。



つまり、これは「apacheのタイムアウトですよ」と読み替えることが出来そうだ。
で、実際アップロードする時間を測ってみると、
3000行くらいは1分40秒くらいでアップできているけど、
5000行になると、5分超えたあたりでInternal Server Error。

httpd.confを触れない以上、apacheのタイムアウトを伸ばすことも出来ないし、
apacheのタイムアウトは多分デフォルトの300秒(5分)になってるだろうから、
3000行以内でアップしてねー、っていう運用側カバーしてもらうことで幕。





ってか、アップロードに時間かかりすぎじゃない?
それに使った変数開放してねぇから、スワップしてんだろこれ。
3000と5000で倍以上の開きがあるってことはさ。。。
DBの処理とか詰め甘いんじゃねぇの?EC-CUBEさんよ。

共用サーバーは、共用だからまぁ仕方ないとしてもさ、
EC-CUBEはきらい。
なんか色々調べてたら、「これ以上のことは有償で対応します」的なこと書いてあったし。
EC-CUBE嫌い。



ちなみにこれ調べてる時に、EC-CUBEの管理画面で、
システム設定>EC-CUBE ログ表示
でエラーログ見たら、こんなエラーがアホほど出てた。

arning(E_WARNING): array_diff() [function.array-diff]: Argument #1 is not an array on [/*************/data/class/SC_CheckError.php(63)] from 000.000.000.000

これってさ、PHPでarrayじゃない奴をarray_diff()って関数に突っ込むと出るんだよね。
デフォルトでアップした行数分出るみたい。
それぐらいさぁ。。。

ちなみにこれの対策は、/data/class/SC_CheckError.phpの63行目に

$arrDiffTag = array_diff($arrTagIncludedHtml[1], $value[2]);

こんな記述があるから、こいつを
$arrDiffTag = array();
if(is_array($arrTagIncludedHtml[1]) && is_array($value[2])){
$arrDiffTag = array_diff($arrTagIncludedHtml[1], $value[2]);
}

とかにしてやれば出なくなる。
EC-CUBEの次回バージョンUPで対策するそうな。



あぁ、疲れた。


なんかなぁ。
「ITの人」って同じくくりにされるのが本当に嫌。

AD
いいね!した人  |  コメント(0)

[PR]気になるキーワード