О dxfoto.ru: О миграции

Почти без матов, совсем без перекуров переехали из AWS в YC

Нет, физически мы никуда не едем. Но так уж вышло, что по независящим от нас причинам нам пришлось съезжать с AWS, долго служившим нашему сайту домом. Жаль, но что поделаешь. Не мы это придумали.

Путём бросания кубика подкидывания монетки мужественного решения от фонаря целевой платформой было выбрано Яндекс.Облако. В принципе, нам не так много и надо — мы используем объектное хранилище и облачные функции.

Объектное хранилище

С самим объектным хранилищем сложностей особо нет, пересунуть 15 гигабайт с одного облака в другое — задача элементарная, хоть и занимает какое-то время. Но хранилище существует не само по себе, с ним взаимодействуют различные процессы — сборочный пайплайн (он остался в Github Actions), локальные редакторские скрипты, облачные функции. И вот тут местами повылезали грабельки. Самой противной и трудозатратной (аж час времени, включая отладку пайплайна, где этот вызов используется) оказалась простановка редиректа для «сегодняшней» фоточки. Хотя Object Storage Яндекса имеет совместимое с S3 API, оно реализует его не на 100%. В S3 работало так:

# предварительно пишем в файл today полный URL целевого объекта
aws s3api put-object --bucket img.dxfoto.ru \
                     --key today.jpg \
                     --website-redirect-location $(<today)
aws s3api put-object-acl --bucket img.dxfoto.ru \
                         --key today.jpg \
                         --acl public-read

Но Яндекс так работать не возжелал. Яндекс предложил перезаливать конфиг статического сайта, что немного сложнее. Т.о. вместо файлика с единственной строчкой нам теперь понадобится целый JSON, что-то такое:

// Немного поправили генератор для Jekyll,
// переменная date содержит почти целиком префикс объекта.
// А раньше просто писали этот префикс в файл, без танцев.
{
  "ErrorDocument": {
    "Key": "index.html"
  },
  "IndexDocument": {
    "Suffix": "error.html"
  },
  "RoutingRules": [
    {
      "Condition": {
        "KeyPrefixEquals": "today.jpg"
      },
      "Redirect": {
        "HostName": "img.dxfoto.ru",
        "HttpRedirectCode": "301",
        "Protocol": "https",
        "ReplaceKeyWith": "l/#{date}.jpg"
      }
    }
  ]
}

Соответственно, поменялся и вызов API в пайплайне:

aws --endpoint-url=https://storage.yandexcloud.net \
    s3api put-bucket-website \
    --bucket img.dxfoto.ru \
    --website-configuration file://today.json

В процессе модификации пайплайна была также найдена ошибка в настройке его кэширования. Из-за этого неправильно формировались подсказки для оборудования. Убрали лишние пути из кэша, теперь должно работать как надо.

Облачные функции

Тут работы было много. В первую очередь, было решено отказаться от Blitline: каких-то невероятно сложных действий в нём не производится, а конфигурация ради взаимодействия с ним гораздо сложнее. Всё, что нам нужно — это получать из исходной большой картинки несколько поменьше (плюс оптимизация по дороге) и выдёргивать несколько тегов EXIF, которые надо сохранить в отдельный бакет, а их потом возьмёт пайплайн.

В AWS по триггеру, срабатывавшему на загрузку картинки в бакет hd.dxfoto.ru, дёргается задачка для Blitline. Тот по завершении кладёт уменьшенные картинки в бакет img.dxfoto.ru, а также подёргивает API Gateway, который запускает ещё одну лямбду, которая сохраняет журнал работы Blitline и EXIF картинки.

Всё это можно замечательно переписать на одну единственную функцию на, скажем, python — это прекрасно умеет делать чудесная библиотека pillow. Ну, чуть-чуть математики на уровне 5 класса нужно вспомнить.

Образовался, правда, затык с обрабокой EXIF: старательно наколупанная функция, полная магических чисел (на самом деле — номера тегов всего лишь) отлично работала на моей машине, но падала с невнятной ошибкой в облаке. Путём пристального посмотрения на различия было выявлено: у меня python 3.8, pillow 6, в облаке соответственно 3.9 и 9. Понижение версии python в облаке эффекта не возымело, а вот повышение версии pillow у меня — очень даже. Да, тоже перестало работать. Экспериментально было выяснено, что на 9 версии получение EXIF работает как-то совсем никак, на 8 работает, но отличается от 6. Ну, тут уже цель понятна: понизили версию на облаке, доработали функцию с учётом отличий. Заодно отказались от сохранения ненужных тегов, чё место занимать будут.

Заключение

Ну, по большому счёту и всё. Ну, добавили ещё в функцию ресайза сохранение в webp, но на сайте оно пока никак не используется — нужно отконвертировать все существующие картинки предварительно. Инфу о хостинге в футере подправили.

Пока, AWS! Привет, Yandex.Cloud!

 2022-03-13
dxfoto
cloud