
Содержание статьи
Да, вы правильно прочитали: эта статья посвящена запуску Google Chrome (браузер) в AWS Lambda (бессерверная вычислительная платформа). Зачем кому-то запускать браузер на сервере[less] сторона? Это какая-то веб-версия «Will It Blend?»
Как бы я не хотел видеть (или делать) бессерверный «Will It Blend?» серия, запускающая странные вещи в AWS Lambda, это не то.
Но что это за статья? Ладно, пришло время истории!
Когда-то в Cloud Horizon мы работали с клиентом, у которого были странные SVG файлы, которые нужно было конвертировать в PNG. Ни один из инструментов SVG-to-PNG не работал, поскольку SVG содержали <foreignObject>
элементов.
Эту проблему можно было решить многими разными способами. Оптимальным решением было бы проанализировать, почему у них есть элементы HTML, встроенные в файлы SVG. Но, как это часто бывает в реальных проектах, причина была скрыта за кучей устаревшего кода и устаревших решений. И, конечно, решение требовалось как можно скорее.
Поиск идеального решения стал поиском скорейшего достойного решения в данных обстоятельствах.
Посторонние объекты в SVG были элементами HTML, а лучшим инструментом для отображения элементов HTML является обозреватель. Но как мы можем использовать браузер для решения этой проблемы?
Вручную мы открываем SVG в браузере и снимаем экран. Мы должны иметь возможность сделать то же самое с PhantomJS, безголовым сценарием WebKit с JavaScript API. Мы попробовали, но это не сработало из-за отсутствия поддержки сторонних объектов SVG в PhantomJS.
Что еще мы могли бы использовать? Представьте, что мы используем Chrome, как мы используем PhantomJS. Подождите! Может быть, мы сможем это сделать. Кто-то из команды недавно читал о безголовом Chrome. Это звучало как идеальный инструмент для нашей удивительной проблемы. Мы попытались использовать безголовый Chrome, и это сработало!
Решите проблему, не причиняя вреда себе в будущем
Наконец-то мы нашли жизнеспособное решение. Но нам нужно было выяснить, как интегрировать это решение в клиентскую программу без добавления дополнительного слоя будущего устаревшего кода.
Наш клиент использовал AWS, а файлы SVG были в пакете Amazon S3. Это дало нам возможность использовать бессерверный для конвертера SVG в PNG.
Бессерверные решения дешевы, а для такого типа конвертеров они были бесплатными, поэтому нам не нужно разрешение на его использование. Это, а также тот факт, что инфраструктура не нуждалась ни в какой настройке, позволили нам быстро двигаться. Еще одной большой победой стала изоляция, позволившая нам работать, не понимая устаревшего кода. Кроме того наш бессерверный конвертер будет легко удалить в будущем.
Краткое примечание: Бессерверный – это метод развертывания и запуска программ в облачной инфраструктуре с оплатой использования без аренды или покупки серверов. Чтобы узнать больше о бессерверных программах и как это работает с AWS, просмотрите бесплатный первый раздел нашей новой книги «Бессерверные программы с Node.js» здесь.
Как показано на схеме ниже, наш план был следующим:
- Клиент загружает файлы SVG в сегмент S3 по-прежнему.
- S3 запускает функцию AWS Lambda.
- Внутри функции Lambda Node.js скачивает SVG из сегмента S3 и запускает Chrome без головы.
- Headless Chrome загружает SVG и снимает экран.
- Приложение Node.js затем загружает изображение скриншота PNG обратно в ведро S3.
- Клиент использует изображение PNG из сегмента S3.

Покажи мне код
Мы решили использовать Node.js, поэтому первым шагом было проверить, существует ли Google Chrome для AWS Lambda в NPM. Мы не были разочарованы: пакет под названием «бессерверный хром» защищал нас.
Примечание: AWS Lambda работает на Amazon Linux. Чтобы запустить библиотеку сторонних разработчиков, например Google Chrome, необходимо собрать ее как статический двоичный файл с помощью Amazon Linux. Чтобы узнать больше об этом процессе, просмотрите здесь, как собрать и запустить Pandoc на AWS Lambda.
Еще одним недостающим элементом был способ взаимодействия с Google Chrome в AWS Lambda. Самая популярная библиотека, Puppeteer, казалась достаточно обширной для этой задачи, поэтому мы использовали интерфейс chrome-remote-interface.
Давайте возобновим проект вместе. Но прежде чем это сделать, есть две предпосылки:
- Вам нужно установить Node.js из npm.
- Вам нужно иметь аккаунт AWS и настроить учетные данные (смотрите, как это сделать здесь).
Чтобы установить обе зависимости, вам следует инициировать новый проект Node.js и выполнить следующую команду в своем терминале:
npm install @serverless-chrome/lambda chrome-remote-interface --save
Эта лямбда-функция невелика, и вы можете вместить ее в один файл и менее 100 строк кода. Но чтобы сделать нашу функцию проверенной, мы будем использовать структуру, показанную на рисунке ниже.

Как вы тестируете бессерверные функции? Концепция похожа на любое другое приложение Node.js: вам следует применить гексагональную архитектуру, а затем вы можете использовать свой любимый инструмент Node.js для тестирования. Наш выбор – Жасмин. Если вы хотите узнать больше о тестировании приложений без сервера, вы можете просмотреть раздел тестирования нашей книги здесь.
В нашей структуре файл index.js просто обрабатывает событие, передает его функции конвертеру и отвечает. Этот файл должен выглядеть как этот фрагмент кода:
Опять же, для целей тестирования логика конвертора находится в следующих файлах:
convert.js
: основной файл, соединяющий все остальные файлы.download-from-s3.js
: функция, загружающая SVG из сегмента S3.save-svg-and-get-dimensions.js
: функция, которая сохраняет SVG-файл в файле/tmp
папку и считывает ее размеры.screenshot-with-headless-chrome.js
: функция, которая загружает файл в безголовом Chrome и делает снимок экрана.upload-to-s3.js
: функция, загружающая снимок экрана (файл PNG) обратно на S3.
Большинство файлов просты и содержат всего несколько строк кода. Но чтобы эта статья была короткой, давайте рассмотрим самые важные из них: convert.js
и screenshot-with-headless-chrome.js
.
Как вы можете видеть в следующем фрагменте кода, функция конвертации выполняет следующее:
- Загрузка файла SVG из S3 с помощью функции с
download-from-s3.js
файл. - Подготовка пути к файлу SVG в
/tmp
папку и вызов функции для сохранения файла SVG и получения размеров по умолчанию. - Открытие локального SVG-файла в безголовом Chrome и создание снимка экрана с помощью функции с
screenshot-with-headless-chrome.js
файл. - Загрузите снимок экрана в ведро S3 с помощью функции from
upload-to-s3.js
файл.
Запуск Chrome без головы
Последним важным элементом этой головоломки является запуск Chrome без головы. Для этого мы запустим Chrome с помощью @serverless-chrome/lambda
модуль, а затем взаимодействовать с ним с помощью chrome-remote-interface
модуль.
Удаленный интерфейс Chrome получает список всех вкладок и подключается к первой. Затем он активирует страницу и сеть клиента.
Когда страница и сеть готовы, удаленный интерфейс Chrome переходит к указанному вами URL-адресу (локальный file://
путь к файлу SVG), ждет его загрузки и делает снимок экрана.
Код screenshot-with-headless-chrome.js
файл должен выглядеть как фрагмент кода:
Теперь, когда код готов, пора развернуть его в AWS Lambda. Но поскольку Google Chrome превышает ограничение в 50 МБ для AWS Lambda, развертывание происходит не так гладко, как можно было бы ожидать.
Как мы можем вдавить слона в багажник автомобиля?
С приложениями без сервера вы часто получаете больше кода для автоматизации развертывания, чем для бизнес-логики программы. Это признак того, что риск перешел на развертывание. Поэтому процесс развертывания должен быть проверен и которым можно доверять.
Чтобы избежать неожиданных проблем, мы используем Claudia.js для развертывания бессерверных приложений Node.js на AWS Lambda и API Gateway.
С Claudia.js мы обычно делаем это claudia create --region eu-central-1 --handler index.handler
. Но в случае безголового Chrome эта команда не удается из-за размера пакета, который вы пытаетесь развернуть.
AWS Lambda имеет ограничение в 50 МБ на размер пакета развертывания для сжатых файлов. К счастью, существует также ограничение в 250 МБ для несжатого кода, который вы можете использовать через ведро S3. Код загружается в сегмент S3, а затем передается в функцию AWS Lambda без сжатия.

Чтобы сделать это с Claudia, выполните следующую команду:
claudia create --region eu-central-1 --handler index.handler --memory 1024 --timeout 60 --use-s3-bucket S3_BUCKET_NAME
Важные примечания к предыдущей команде:
- Заменить
S3_BUCKET_NAME
с названием ведра S3, которым вы владеете. Вы можете создать новый и использовать его просто в качестве помощника для развертывания. - Выберите любой регион, к которому вы ближе всего, просто убедитесь, что лямбда-функция находится в том же регионе, что и вспомогательный сегмент S3. Просмотрите все поддерживаемые регионы здесь.
- Если ваш основной файл имеет другое название, вам нужно будет обновить обработчик в команде имени файла с помощью
.handler
вместо.js
расширение. Например, если имя файла естьmain.js
ваш обработчик будетmain.handler
. - Несколько увеличьте память по умолчанию, поскольку Chrome без головы требует больше, чем стандартные 128 МБ.
- Увеличьте время ожидания (несколько секунд должно быть достаточно). Но поскольку вы не платите за тайм-аут, а только за фактическое время исполнения, вы можете добавить чуть больше даже около 5 минут (максимум).
Через несколько минут (в зависимости от скорости Интернета) вы увидите подтверждение того, что все было успешно развернуто.
Примечание: Если вы хотите обновить свой код, запустите claudia update --use-s3-bucket S3_BUCKET_NAME
команда. Чтобы узнать, как использовать Claudia.js, см. раздел учебника на веб-сайте.
Последним шагом перед тестовой поездкой является настройка триггера S3 для функции Лямбда. Клаудия тоже покрыла вас. Просто запустите такую команду из своего терминала:
claudia add-s3-event-source --bucket S3_BUCKET --suffix svg
Снова замените S3_BUCKET
с названием сегмента S3, используемого для файлов SVG и PNG. По умолчанию PNG сохраняется в той же папке, где находится файл SVG.
И когда команда выполняется успешно это все. Ваш бессерверный конвертер файлов готов.
Тестовый заезд
Настало время для пробной поездки!
Итак, как проверить бессерверный конвертер? Просто загрузите файл SVG в сегмент S3. И что тогда? Обновите ведро через несколько секунд, и вы увидите файл PNG с таким же названием. Вы будете удивлены, насколько быстро это действительно работает! Headless Chrome, кажется, быстрее браузера Chrome на моем компьютере. Возможно, теперь мне следует просматривать Интернет в безголовом режиме. ?
Подведению
Таким образом, мы решили проблему нашего клиента, не причиняя вреда себе в будущем. Это не самое лучшее решение, но это было самое лучшее решение, которое мы смогли придумать за короткий промежуток времени и учитывая обстоятельства.
Но каков смысл этой истории? Почему вам нужно запустить Chrome в AWS Lambda, если у вас нет клиента?
Существует много возможных случаев использования. Если вы помните пирамиду тестирования, тесты UI медленные и дорогостоящие. Но что если вы можете запустить несколько сотен или даже тысяч их параллельно и платить только за время выполнения? Существуют некоторые инструменты тестирования пользовательского интерфейса, которые уже работают над подобной интеграцией, например Appraise.

Надеюсь, вам понравилась история. Скоро ждите больше!
Как всегда, большое спасибо моим друзьям Александру Симовичу за помощь и отзыв о статье.
Все иллюстрации созданы с помощью программы SimpleDiagrams4.
При создании этой статьи ни одна корова не пострадала.
Если вы хотите узнать больше о создании и тестировании бессерверных программ с помощью Node.js и AWS, посмотрите книгу «Бессерверные программы с Node.js», которую я написал вместе с Александром Симовичем для Manning Publications:
Бессерверные программы с Node.js
Убедительное вступление в бессерверное развертывание с помощью Claudia.js.www.manning.com
Книга научит вас больше о бессерверных программах с примерами кода. Вы узнаете, как создать и настроить реальный бессерверный API (с базой данных и аутентификацией) с помощью Node и Claudia.js. И вы узнаете, как создавать чат-боты для Facebook Messenger и SMS (с помощью Twilio), а также навыки Alexa.