Как ускорить работу image style ?

Главные вкладки

Аватар пользователя W32 W32 22 февраля 2011 в 19:33

Очень медленно работает модуль image-style (бывший imagecache). Как только идет одновременно несколько запросов на большое кол-во картинок начинаются жуткие тормоза, хотя для всех картинок соответствующие стили уже давно построены и лежат в папке style. Загрузка процессора 100% - почти все съел аппач. Я поставил APC, ситуация стала чуть легче, но не значительно.
Как избавиться от этого ступора?

Комментарии

Аватар пользователя W32 W32 22 февраля 2011 в 20:28

Верно. Просто image...
Картинки все закешированы, лежат себе для всех стилей в public директории. Я думаю, может image пытается проверить не устарели ли они, все на это у него уходит много времени (хотя странно почему) ?
Графическая библиотека - стандартная, пытался прикрутить ImageMagick - но он по виндой такой глюкавый (не понимет пути к файлу на диске если там русские символы), а для GrapichMagick еще модуля не сделали для D7.

Аватар пользователя Ch Ch 22 февраля 2011 в 21:00

А почему, вы решили что виноват image? Существующие файлы в public отдаются сразу, друпал тут даже не участвует.

Аватар пользователя W32 W32 23 февраля 2011 в 10:29

Ch wrote:
А почему, вы решили что виноват image? Существующие файлы в public отдаются сразу, друпал тут даже не участвует.

Потому, что ссылки сгенерированные image ведут не на public папку, а обрабатываются хуком из image. Вот если файл в кеше не устарел, то image должен был по идее переправить ссылку на чистый public для отдачи. Но, похоже что тут как раз и тормоза.

Аватар пользователя bsyomov bsyomov 22 февраля 2011 в 21:55

Алгоритм работы должен быть такой:
1. Веб сервер пытается найти файл на диске, если есть, отдаёт её, друпал в общем-то не участвует в этом процессе...
2. Если его нет, вызывается скрипт который генерит картинку и отдаёт её.
Похоже на то, что у вас первая часть алгоритма не работает, и каждый раз запускается генерация картинки. Если это так, у вас скорее всего что-то не то наверчено в .htaccess или в конфигурации сервера. Как конкретно вам удалось добиться такого поведения и где вы ошиблись, не видя конфигов не определить.

Да, без apc или аналогов вообще жить нельзя - это первое, что надо ставить, если у вас исполняется хоть сколько-то большой php код. Smile

Аватар пользователя W32 W32 23 февраля 2011 в 10:31

"bsyomov" wrote:
Алгоритм работы должен быть такой:
1. Веб сервер пытается найти файл на диске, если есть, отдаёт её, друпал в общем-то не участвует в этом процессе...
2. Если его нет, вызывается скрипт который генерит картинку и отдаёт её.

спасибо, попробую разобраться. только первая часть не такая... я уже об этом писал в предыдущем ответе.
Так что при обработке ссылок от image php запускается всегда, есть ли файл на диске или его нет.

Аватар пользователя Ch Ch 23 февраля 2011 в 11:12

"W32" wrote:
Так что при обработке ссылок от image php запускается всегда, есть ли файл на диске или его нет.

Почему вы так решили?

Аватар пользователя W32 W32 23 февраля 2011 в 11:50

"Ch" wrote:
Почему вы так решили?

Потому что ссылки построенные через image имеют вид:
домен сайта/sites/default/files/pub/styles/имя стиля/public/images/картинка.jpg
в то время как путь кеш-картинке домен сайта/sites/default/files/pub/images/картинка.jpg

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

Аватар пользователя W32 W32 23 февраля 2011 в 11:59

Блин.... так и есть... полные тапочки!
Посмотрите код метода image_file_download() - это и есть хук из модуля image(). Даже если кеш не устрале - скачивание файла идет через ядро друпала (вызвается метод file_file_download())

Аватар пользователя Ch Ch 23 февраля 2011 в 12:07

"W32" wrote:
первый путь - виртуальный, он обрабатывается хуком. его смысл - проверить не устарел ли кеш и нужно ли его перестроить.

Почему он вдруг виртуальным стал?
У меня этот путь вполне реальный. И в нём лежат реальные картинки, обработанные с в соответствии с заданным стилем.
Возможно, вы просто права на папки не выставили. Проверьте журнал.

Аватар пользователя W32 W32 23 февраля 2011 в 12:32

"Ch" wrote:
Почему он вдруг виртуальным стал?

вы правы, я не совсем правильно выразился... путь не виртуальный, а реальный. но на нем висит хук image_file_download(), который для каждой картинки которая там есть выполняет image_get_info(), чтобы убедится что файл есть и это реальная картинка... потом делает на нее module_invoke_all('file_download', исходная картинка) и только потом дает добро на скачивание! (см. код http://api.drupal.org/api/drupal/modules--image--image.module/function/i...)

Аватар пользователя Ch Ch 23 февраля 2011 в 12:50

Метод загрузки - публичный? Если да, то ни какие хуки для уже сущствующих картинок НЕ выполняются. Потому что, в этом случае друпал даже НЕ запускается. Апач просто берет эту картинку и отдает ее пользователю.
Если конечно вы не меняли .htaccess. Это всё легко проверить.

Аватар пользователя W32 W32 23 февраля 2011 в 13:08

По умолчанию метод загрузки - приватный, в 7м друпале оба метода работают паралельно. картинки о которых идет речь лежат в публичной секции.

Содержимое .htaccess из публичного каталога:
SetHandler Drupal_Security_Do_Not_Remove_See_SA_2006_006
Options None
Options +FollowSymLinks

Содержимое .htaccess из приватного каталога:
SetHandler Drupal_Security_Do_Not_Remove_See_SA_2006_006
Deny from all
Options None
Options +FollowSymLinks

Аватар пользователя W32 W32 23 февраля 2011 в 13:30

Ch , вы натолкнули меня на мысль...
я только что перепроверил ссылки, оказывается они имеют вид:

домен сайта/ru/sites/default/files/pub/styles/имя стиля/public/images/картинка.jpg

сайт работает на двух языках. Английский и русский, для обоих локаций включены коды en и ru соответсвенно. Ссылки на картники генерируются через image_style_url('medium', $value->uri); и в результате код локации попадает в путь. Естественно такого пути к файл физически нет и происходит загрузка через друпал. Как бороться ?

Аватар пользователя W32 W32 23 февраля 2011 в 13:48

Давайте внимательно посмотрим на ф-ю image_style_url() - http://api.drupal.org/api/drupal/modules--image--image.module/function/i...
Она для формирования ссылки использует метод url() который и добавляет в путь код локации! Как от этого избавиться.

Аватар пользователя Ch Ch 23 февраля 2011 в 13:54

1. Сначала разберитесь какой именно у вас метод приватный или нет.
2. Отключите один язык и проверьте как это все будет работать.

Аватар пользователя W32 W32 23 февраля 2011 в 14:21

1. У друпала 7 оба метода работают одновременно! Один из них является методом по умолчанию (используется когда в uri не заданна конкретно схема метода puvlic:// или private:// ). У меня методом по умолчанию стоит приватный. Но картинки грузятся из публичной папки публичным же методом (все uri вида - puvlic://images/картинка.jpg).

2. Не могу - оба языка должны быть функциональны.

Я попробовал так - заменил вызов метода image_style_url() на file_create_url( image_style_path() ). Т.е. убрал и процесса формиррвания пути метод url(). Все ссылки начали генерироватся как и положено для ресурсвом - домен сайта/sites/default/files/pub/styles/имя стиля/public/images/картинка.jpg без кода локации.
И все залетало, ура!!! друпал теперь не вызывается.

Но. теперь же надо разобраться чего это вдруг image_style_url() вызывет внутри метод url() и не задает ему опцию - пропускать код локации. Т.к. код локации для статических ресурсов (которыми являются картинки) просто ненужен!