web-dev-qa-db-ja.com

PHP getimagesizeを介したループバック接続がサーバーをクラッシュさせる(Magento CMS)

次のポイントまで、Magentoを実行しているNGINXサーバーをクラッシュさせる問題を追跡することができました。

背景情報:Magentoバックエンドには、WYSIWYGエディターを備えたCMS機能があります。このエディターは、Magento(cms /ディレクティブ)のコントローラーを介していくつかの画像をロードします。

NGINX error_logレベルをinfoに設定すると、次の行が表示されます(読みやすくするために改行が挿入されています)。

_2012/10/22 18:05:40 [info] 14105#0: *1 client closed prematurely connection, 
  so upstream connection is closed too while sending request to upstream, client: 
  XXXXXXXXX, server: test.local, request: "GET 
  index.php/admin/cms_wysiwyg/directive/___directive/BASEENCODEDIMAGEURL,,/ 
  HTTP/1.1", 
  upstream: "fastcgi://127.0.0.1:9024", Host: "test.local" 
_

デバッガーでコードをチェックするとき、次の呼び出しは返されません(´Varien_Image_Adapter_Abstract :: getMimeType() `

_# $this->_fileName is http://test.local/skin/adminhtml/base/default/images/demo-image-not-existing.gif` 
# $_SERVER['REQUEST_URI'] = http://test.local/admin/cms_wysiwyg/directive/___directive/BASEENCODEDIMAGEURL

list($this->_imageSrcWidth, $this->_imageSrcHeight, $this->_fileType, ) = getimagesize($this->_fileName);
_

ファイル名のリクエストは

  • スクリプトを要求しているのと同じサーバーへのURL
  • 存在しない静的な.gifへのリンク。

サンプルURL:

_http://test.local/skin/adminhtml/base/default/images/demo-image-not-existing.gif_

上記の行が実行されると、NGNIXサーバーへの後続の要求はそれ以上応答しなくなります。約10分待った後、NGINXサーバーは再びリクエストへの応答を開始します。

指定されたURLでgetimagesize()を呼び出すだけの簡単なテストスクリプトでエラーを再現しようとしましたが、これはクラッシュしません。それは単純にURLをロードできなかったという例外につながります(URLが間違っているので問題ありません)

3
Alex

現在の理論:

NGINX/PHP FCGIには、処理できるプロセスの数が限られています。CMSWYSIWYGエディターは、NGINXが完了しようとするcms_wysiwyg/directiveアクションで約5つの並列リクエストを起動します。NGINXができるとしましょう。 5つの並列リクエストのみを処理する:NGINXは、これらの実行中のリクエストの1つに追加のリクエストを送信しますが、スロットがいっぱいであるため、もちろん実行できません。1つのリクエストの実行は、追加の1つのリクエストの実行に依存するため、スロットも解放できません。リクエスト。

可能な解決策:

  • スロット数を増やす
  • スロットがいっぱいになると、リクエストが早く失敗するようにします
1
Alex

ここでもほぼ同じ問題が発生しました。アップロードされた画像を含むCMSブロックを表示した後、php/php-fpmセットアップ全体が応答しなくなりました。

問題はgetimagesizeの呼び出しであることが判明しました(私の場合、lib/Varien/Image/Adapter/Gd2.phpの72行目あたり)。問題の画像ファイルはサイト自体にありましたが、getimagesizeのパラメータはHTTPURLでした。奇妙なファイアウォール構成のため、サーバーはHTTP経由で自身に接続できなかったため、リクエストがハングし、理由は不明ですが、php-fpmはリクエストの処理をすべて停止しました。

最後に、nginxは忍耐力を失い、タイムアウトエラーを記録しました。

サーバーが自身に対してHTTP要求を行うことを許可した後、タイムアウトエラーはなくなりました。

MagentoがHTTPを介してローカルファイルにアクセスする理由にはまだ戸惑っていますが、wysiwygエディターで外部画像をサポートする最も簡単な方法でした。

(Magento 1.8.1.0)

0
Saustrup