Yandex Cloud: on the fly thumbnails

Nikolay Matrosov

--

UPD: Yandex.Cloud представили новый runtime для функций — C#. Ну и мне тут же захотелось его попробовать. Поэтому я дописал реализацию этой функции еще и на csharp. https://github.com/nikolaymatrosov/yc-on-the-fly-thumbnailer-csharp/blob/master/OnTheFlyResize/Handler.cs

В прошлом посте я рассказал как создавать превью картинок загружаемых в объектное хранилище Яндекс Облака. У того решения было пара ограничений:

  1. Превью создавались только для новых изображений. Если картинка уже лежит в бакете, то для нее не появится уменьшенная версия.
  2. Нужно было заранее определить высоту и ширину. Если вам понадобилось бы поменять соотношение сторон или размеры, то пришлось бы заново масштабировать все картинки.

Как же будет работать новая схема?

Первое обращение за превью
  1. Пользователь запрашивает картинку, указав в URL ее желаемые размеры.
  2. Объектное хранилище не находит нужного файла и согласно настроенным правилам, переадресует запрос в функцию.
  3. Функция идет за оригинальным изображением в объектное хранилище.
  4. Масштабирует его до нужных размеров и сохраняет по ключу содержащему эти размеры.
  5. И тут же отдает готовый файл пользователю.

Что произойдет при повторном обращении к этому изображению?

Все последующие запросы

Пользователь сразу получит файл из объектного хранилища. Функция даже не будет вызвана.

Как это работает?

Чтобы Object Storage и Cloud Functions заработали в связке нам необходимо прописать правила переадресации для бакета.

s3.putBucketWebsite({
Bucket: "%bucket_name%",
WebsiteConfiguration: {
IndexDocument: {
Suffix: "index.html"
},
RoutingRules: [
{
Condition: {
HttpErrorCodeReturnedEquals: "404",
KeyPrefixEquals: "images/"
},
Redirect: {
HttpRedirectCode: "302",
HostName: "functions.yandexcloud.net",
Protocol: "https",
ReplaceKeyPrefixWith: "%function_id%?path=",
}
}
]
}
})

Если объектное хранилище не найдет (HttpErrorCodeReturnedEquals: "404") запрошенный файл с указанным KeyPrefixEquals , то применит указанный ниже редирект. Подробнее можно посмотреть в документации к AWS S3.

Код функции можно найти в репозитории. https://github.com/nikolaymatrosov/yc-on-the-fly-thumbnailer

Стоит так же отметить, что с момента написания предыдущего поста, создание функций из CLI yc стало гораздо удобнее. Теперь не нужно самому заморачиваться на архивирование кода и загрузку его в объектное хранилище. Достаточно лишь сложить все файлы в директорию и указать на нее при создании версии функции в ключе --source-path .

Так же стало возможным не передавать все node_modules, а загрузить лишь package.json и выбрать --runtime nodejs12-preview. Все зависимости будут подтянуты в момент создания версии функции.

Как обращаться к файлам?

По обычному хосту %bucket_name%.storage.yandexcloud.net редиректы отрабатывать не будут, к объектам нужно обращаться через %bucket_name%.website.yandexcloud.net/PREFIX/%width%x%height%/%path% . Например:

%bucket_name%.website.yandexcloud.net/images/500x500/cats/meow.png

Мы получим картинку которую положили в бакет %bucket_name% по ключу images/cats/meow.png но отмасштабированную до размеров 500x500px.

Чтобы не выстрелить себе в ногу

Если не задать значение переменной окружения ALLOWED_DIMENSIONS , то в функции не будут накладываться ограничений на размеры. Это значит, что если будут запрошены много разных вариантов размеров, то они будут созданы и загружены в объектное хранилище. Поэтому если вы точно знаете, что вам понадобятся определенные размеры картинок лучше их указать.

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

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

--

--

No responses yet

Write a response