Как стать автором
Обновить

Генератор миниатюрок из Nginx-а

Время на прочтение3 мин
Количество просмотров27K
Итак, сегодня мы соберём генератор миниатюрок на базе любимого народом веб-сервера — nginx-а. Что примечательно, сделаем мы это без единого гвоздя, т.е. без единой строчки кода, не считая конфигурации.

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

Для дела нам понадобится ngx_http_image_filter_module, модуль, который умеет трансформировать изображения в форматах JPEG, GIF и PNG. Модуль стандартный, но по-умолчанию не собирается, поэтому перед сборкой нгинкса нужно добавить его:
./configure --with-http_image_filter_module
Теперь ставим libgd способом, принятым у нас в системе, и собираем нгинкс. Кстати, при сборке из портов FreeBSD достаточно выполнить make config и выбрать нужный модуль в списке.

Просто пережимка
Для простоты будем считать, что у нас есть домен images.domain.ru, с которого выдаются картинки лежащие в /path/to/images. Запросы к /some/image.jpg будут выдаваться напрямую, к /120x90/some/image.jpg или /120x-/some/image.jpg будут жаться в миниатюрки (во втором случае идёт масштабирование только по ширине). В таком случае получаем:
server {
    server_name images.domain.ru;
    root /path/to/images;

    if ($uri ~ ^/(\d+|-)x(\d+|-)/) {
        set $w $1;
        set $h $2;
    }

    location / {
    }

    location ~ ^/(?:\d+|-)x(?:\d+|-)/.*\.(?:jpg|gif|png)$ {
        rewrite ^/[\w\d-]+/(.*)$ /$1;
        image_filter resize $w $h;
        break;
    }
}

Что тут происходит? Сначала мы определяем размеры миниатюрки и устанавливаем соответствующие переменные. Затем выдаём статику и переходим к выдаче миниатюрок, рассмотрим второй location по-подробнее: rewrite перенаправляет url на настоящий файл, image_filter уменьшает полученную картинку, break предотвращает внутренний редирект с выходом из location. Последнее важно иначе нгинкс пройдёт весь путь ещё раз с уже переписанным URL и выдаст полную картинку.

Можно добавить предопределённые размеры:
if ($uri ~ ^/small/) {
    set $w 120;
    set $h 90;
}

location ~ ^/(?:\d+|-)x(?:\d+|-)|small/.*\.(?:jpg|gif|png)$ {
    ...

Этим можно уже пользоваться если не жалко процессора, к слову на FreeBSD 8/Core 2 Quad Q9550 @ 2.83GHz/DDR2-800 удавалось пережимать 200 картинок в секунду (jpeg, 640x480 -> 150x150). Но, конечно, нам процессор жалко, поэтому будем пережатые картинки кэшировать.

Пережимка с кэшированием
Кэшированием в нгинксе занимается ngx_http_proxy_module, кэширует он только то, что проксирует, поэтому нам понадобиться извернутся — будем слушать два порта и проксировать сами себя:
proxy_cache_path /path/to/cache levels=1:2 keys_zone=thumbs:10m inactive=24h max_size=5G;

server {
    server_name images.domain.ru;

    location ~ ^/(?:\d+|-)x(?:\d+|-)|small/ {
        proxy_pass http://localhost:8081;
        proxy_cache thumbs;
        proxy_cache_valid  200      24h;
        proxy_cache_valid  404 415  1m;
    }

    location / {
        root /path/to/images;
    }
}

server {
    listen 8081;

    ... конфигурация пережималки ...
}

Готово, теперь на вышеупомянутой системе нгинкс выдаёт 15000 картинок в секунду, если всё из кэша, — чертовски быстро. Я не буду расписывать настройки, они неплохо расписаны в документации модуля. А полный конфиг можно взять тут.
Теги:
Хабы:
Всего голосов 81: ↑76 и ↓5+71
Комментарии42

Публикации

Истории

Ближайшие события

27 августа – 7 октября
Премия digital-кейсов «Проксима»
МоскваОнлайн
11 сентября
Митап по BigData от Честного ЗНАКа
Санкт-ПетербургОнлайн
14 сентября
Конференция Practical ML Conf
МоскваОнлайн
19 сентября
CDI Conf 2024
Москва
20 – 22 сентября
BCI Hack Moscow
Москва
24 сентября
Конференция Fin.Bot 2024
МоскваОнлайн
25 сентября
Конференция Yandex Scale 2024
МоскваОнлайн
28 – 29 сентября
Конференция E-CODE
МоскваОнлайн
28 сентября – 5 октября
О! Хакатон
Онлайн
30 сентября – 1 октября
Конференция фронтенд-разработчиков FrontendConf 2024
МоскваОнлайн