管理ページの長時間実行リクエストが他のリクエストをブロックする


17

Magentoのバックエンドにログインして、長時間かかるタスク(大きなカタログでのグローバル検索、長時間実行されるデータフローなど)を実行すると、Webブラウザーはそのブラウザーのみで他の管理ページの読み込みを拒否します。なぜこれが起こるのですか?回避策として知られている科学はありますか?

つまり、私が

  1. Magentoのダッシュボードページにログインする

  2. 任意のMagento管理ページで2番目のタブを開きます

  3. 最初のタブで長時間実行するグ​​ローバル検索を実行します(sleep(30)の開始時にへの呼び出しでシミュレートglobalSearchAction

  4. 2番目のタブの再読み込みを試みます

予期される動作:2番目のタブがすぐにページコンテンツと共に読み込まれます

実際の動作:2番目のタブは、長時間実行されるグローバル検索が完了した後にのみ読み込まれます

誰も、具体的に、なぜこれが起こるのか知っていますか?(私の推測では、Magento管理コンソールのリクエストは、Magentoがブートストラップするのに必要なリソースをロックしますが、それが何なのかわかりません)

誰でも修正/回避策を知っていますか?


1
あなたは、私に挑戦を送ったばかりです!:)
ダビダルガー

回答:


21

この問題は、PHPセッションハンドラーによってロックがかけられていることが原因です。ですから、Magentoが何かを明示的にロックして管理リクエストをブロックしようとするのではなく、ファイルベースのセッションストレージの副作用そのものです。

セッションデータファイルが最初の(長時間実行される)要求によって開かれたときにセッションデータファイルに書き込みロックが設定されているため、呼び出し時にロックが解除されるまで2番目の要求がブロックされますsession_startMage_Core_Model_Session_Abstract_Varien::start

これは100%再現可能です。私はあなたがしたのと同じ方法を使用してsleep(30)Mage_Adminhtml_IndexController::globalSearchAction

データベースセッションストレージを使用している場合、これは再現できないことに注意してください。根本原因を見つけた後、サンドボックスをdbセッションストレージに設定しましたが、問題を再現できなくなりました。そのため、Magentoのdbセッションハンドラーは、行レベルのロックを使用してセッション書き込みをロックしていないようです。アプリケーションは明らかに同じセッションに書き込む複数のスレッドを考慮していないため、セッションデータが失われる可能性があるため、これは興味深いと思います。読者への注意:本番環境でdbセッションストレージを使用してこれを解決しようとすることは決してありません。MySqlデータベースのオーバーロードにのみ適しています。

Redisなどのメモリベースのセッションストレージシステムを使用して動作を再現しようとしませんでしたが、セッションストア内のレコードのロックはおそらくこれらでも見落とされていると思われます。

これを回避するためsession_write_closeに、長時間実行されるジョブを開始する前にロックを解除するなどの方法を使用できます。ただし、セッションを閉じたばかりなので、これによりセッションへの書き込みができなくなります。そのため、Magentoでは全面的に容易に実装される可能性は低くなりますが、特定のルート/コントローラーに実装される可能性があります。

これを根本原因として特定するための私のテクニックは、Xdebugプロファイラーを有効にし、「cachegrind」ファイルを調べることでした。2番目の要求が完了したら、出力ファイル(約25 MBのログ)をMacCallGrindにロードし、呼び出し時間が28秒以上の呼び出しのパスに沿ってトレースをドリルダウンしました。これにより、最終的session_startに実行までに約28秒かかった呼び出しに至り、調査の大きなポイントになりました。

編集:興味のある方のために、私はTwitterでMacCallGrindで見た「cachegrind」ファイルのスクリーンショット投稿しました。


UnirgyのuRapidFlowモジュールは、この問題を回避するためにセッションを閉じますが、これはある意味では良いことですが、後でユーザーにフィードバックを提供するのが難しくなるだけでイライラします。
ピーターオキャラハン

@davidalger —クライアントサイト用に通常どのセッションストレージをデプロイしますか?
アランストーム

3
Re:PHPセッションファイルをロックします。これは、ディスク上のファイル自体の整合性よりもデータの整合性の方が劣ります。複数のプロセスを開いてディスク上のビットに書き込むと(ファイルとは)、データがすぐに破損します。MySQL、redis、およびほとんどのデータベースは、ほぼ同時に複数の書き込みがある場合でも、一貫性を保つように特別に設計されています。つまり、ロックが見落とされたということではなく、それほど必要ではないということです。
アランストーム

@AlanStorm —負荷分散インストール用の専用Memcachedインスタンス、単一アプリケーションノードクラスター用のファイルシステム。ファイルシステムは、IPレイテンシがないため、複数のノードがない場合に最高のパフォーマンスを発揮します。
-davidalger

ファイルをロックすると、データの破損を防ぐことができます。ただし、セッションが終了するまでロックを保持することは、データの損失を防ぐことです。2つのプロセスがセッションデータをロードし、変更してから書き出すと、そのうちの1つがその変更を上書きします。一般に重大な問題を引き起こすことはありませんが、データの損失やデバッグが困難な問題を引き起こす可能性があります。
-davidalger
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.