ec-cube
ec-cube copied to clipboard
プラグインのインストールに失敗する問題
概要(Overview)
プラグインのインストール時に高負荷な状態が発生し、OOM Killerでhttpdのプロセスが殺される。そのため、プラグインのインストールが完了しない。
発生時のログは以下の通り。
/var/log/messages
Apr 17 09:57:43 kernel: Out of memory: Kill process 16845 (httpd) score 149 or sacrifice child
Apr 17 09:57:43 kernel: Killed process 16845 (httpd) total-vm:2333820kB, anon-rss:524704kB, file-rss:1400kB, shmem-rss:556kB
Apr 17 09:57:47 kernel: swap_info_get: Bad swap offset entry 0008007c
Apr 17 09:57:47 kernel: swap_info_get: Bad swap offset entry 0008007d
主に以下の2点で、高負荷となっている
- Composer APIによる依存関係の解決
- symfonyのDIコンテナキャッシュの削除と再生成
インストールに失敗した場合、インストール途中のプラグインファイルや、autoloaderのクラスマップ等が中途半端に残ってしまう。現状では復旧の手順が確立していない。
環境 (environment)
- EC-CUBE: 4.0.x
- PHP: 7.x.x
- DB:
- PostgreSQL x.x.x
- MySQL x.x.x
関連情報 (Ref)
- #3990
- #4133, #4106
- BoltやMagentoでもComposerAPIを利用しているため、他のCMSも調査
Magentoでは基本コンソールからcomposer叩きますね。管理画面からはやった事ないです。
共有でも、さくらのレンタルサーバーでは難なく動くので何故かなと考えていたんですが、FreeBSD を採用しているため、 OOM Killer が走らないからみたいですね🤔
bolt の場合、プラグインは独自に composer.json を生成しており、bolt 本体とは別途依存関係の管理をしているようです。 依存関係考慮のスコープが狭いため高速で、本件のような問題は発生しにくい模様
そもそも何でこの処理こんな重いんですか? composerの問題ですか?
@tao-s Composer API の問題と Symfony キャッシュ生成の問題ですね
例えば https://qiita.com/bezeklik/items/f9bc7afc229b5476e822 こういうアプローチでは早くならないんでしょうか?
composer のプラグインはいろいろ試してみる価値ありそうですね。高速化するというより、多少遅くなってでも高負荷にならないようなアプローチができればなと。
インストールに失敗した場合、インストール途中のプラグインファイルや、autoloaderのクラスマップ等が中途半端に残ってしまう。現状では復旧の手順が確立していない。
こちらについて、 @nanasess に 復旧手順を作成いただきました。 https://qiita.com/nanasess/items/583683eb94947aebea44
これらを実行しても解消されない場合、フィードバックをお願いできればありがたいです。
並列化出来ればピークメモリは減りそうですよね〜
手元の環境に hirak/prestissimo
を入れてみましたが、以下のような感じであまり変化無しですね。。。
Memory usage: 496.44MiB (peak: 588.81MiB), time: 50.58s
ダウンロードより、依存関係を解決するためにキャッシュをメモリに読み込んでいるところで、大量のメモリを食ってる感じです。
@nanasess 依存関係の解決でそんなメモリ食うのはやっぱ何かおかしいですね。キャッシュにいらん情報まで入ってんのかな?
@tao-s Symfony のパッケージが多すぎるのも問題なのかなと。bolt のように、 本体とプラグインの composer.json を分ければ改善される気がします
@nanasess 確かに全然変わらないですね。
あれですね Reading /hoge/eccube4/app/Plugin/.composer/cache/repo/https---repo.packagist.org/provider-zendframework$zend-hydrator.json って感じで、パッケージのjsonを全部メモリに読み込むのでどうしようもないっすね
@nobuhiko Symfony の依存パッケージ多すぎる問題ですね...
PHPで書かれてて、symfony/PHP-FPMの代わりになるReactPHP使ってる変なのを見つけました。 symfonyでコマンド叩いて子プロセスを管理するヤツなんですが、こんな感じで react/child-process 使ってcomposer動かせませんかね? そしたら最悪OOM Killerで殺されてもそれを検知できるかな?と https://github.com/php-pm/php-pm
メモリの問題が大幅に改善されるComposer2.0を利用することでこちらの問題は軽減される見通しです。 互換性の問題から4.1での導入となる見通しです。 4.0へのバックポートも模索していますが、現状で見通しは立っていません。
Composer 2.0 Support
#4712
ロリポップのスタンダードプランで確認してみました。
4.0ではシステムエラーでインストールできなかったのが、4.1-RCではインストール/有効/無効/削除すべて実行できました。
4.0
https://user-images.githubusercontent.com/8196725/132176641-8e9cff32-c926-4048-a1fc-df80737b197a.mov
4.1 RC
https://user-images.githubusercontent.com/8196725/132176829-aa27604d-f713-41f4-822b-a8bdebafbad7.mov
herokuでもプラグインのインストール/有効化/無効化/削除ができることを確認しました。
@chihiro-adachi
herokuでもプラグインのインストール/有効化/無効化/削除ができることを確認しました。
Heroku 試してみましたが、プラグイン5個くらい入れたところでシステムエラーになりました。EC-CUBEのログにシステムエラーは無かったので、 memory_limit 越えたのだと思われます

@nanasess ありがとうございます。 プラグインの数によっても上限はありそうですね。
ロリポップ(スタンダード)はmemory_limit300MBだったのでもう少し行けそうな気がします。
構造上、現状ではこれ以上の修正が無理なissueです。 大きなメジャーバージョンアップ時に再度確認が必要なため、マイルストーンをx.xに変更しました。