Назад | Перейти на главную страницу

Петлевое соединение через сервер сбоев getimagesize PHP (Magento CMS)

Мы смогли отследить проблему, которая приводит к сбою нашего сервера NGINX, на котором запущен Magento, до следующего момента:

Справочная информация: Magento Backend имеет функцию CMS с редактором WYSIWYG. Этот редактор загружает некоторые изображения через контроллер в magento (директива cms /).

Когда мы устанавливаем уровень error_log NGINX на 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:

http://test.local/skin/adminhtml/base/default/images/demo-image-not-existing.gif

При выполнении указанной выше строки любой последующий запрос к серверу NGNIX больше не отвечает. Подождав около 10 минут, сервер NGINX снова начинает отвечать на запросы.

Я попытался воспроизвести ошибку простым тестовым скриптом, который вызывает только getimagesize() с заданным URL - но это не сбой. Это просто приводит к исключению, в котором говорится, что URL-адрес не может быть загружен (что нормально, поскольку URL-адрес неверен)

Текущая теория:

NGINX / PHP FCGI имеет ограниченное количество процессов, которые он может обрабатывать. Редактор CMS WYSIWYG запускает около 5 параллельных запросов на cms_wysiwyg/directive действие, которое NGINX пытается завершить. Допустим, NGINX может обрабатывать только 5 параллельных запросов: теперь NGINX делает дополнительный запрос внутри одного из этих запущенных запросов к себе, который, конечно, не может быть выполнен, потому что слоты заполнены. Слоты также не могут быть освобождены, потому что выполнение одного запроса зависит от выполнения одного дополнительного запроса.

Возможные решения:

  • Увеличить количество слотов
  • Позвольте запросам завершаться ошибкой раньше, когда слоты заполнены

У меня здесь была почти такая же проблема. После просмотра CMS-блока, содержащего загруженное изображение, вся установка php / php-fpm перестала отвечать.

Проблема оказалась в вызове getimagesize (в моем случае около строки 72 в lib / Varien / Image / Adapter / Gd2.php). Несмотря на то, что рассматриваемый файл изображения был расположен на самом сайте, параметром getimagesize был URL-адрес HTTP. Из-за странной конфигурации брандмауэра серверу не удалось связаться с самим собой через HTTP, поэтому запрос завис, и по неизвестным причинам php-fpm перестал обслуживать запросы все вместе.

Наконец, nginx потерял терпение и зарегистрировал ошибку тайм-аута.

После разрешения серверу отправлять HTTP-запросы самому себе ошибки тайм-аута исчезли.

Я до сих пор не понимаю, почему Magento получает доступ к локальному файлу через HTTP, но, вероятно, это был самый простой способ поддержки внешних изображений в редакторе wysiwyg.

(Magento 1.8.1.0)