Мы смогли отследить проблему, которая приводит к сбою нашего сервера 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)