- PVSM.RU - https://www.pvsm.ru -
Представляю вам перевод моей статьи на Medium.com: часть 1 [1], часть 2 [2]. Поскольку первая часть статьи содержит в основном уже изложенное в этом посте [3], то привожу перевод только второй части.
В первой части статьи я рассказал о простых подходах, позволяющих построить масштабируемый кластер Selenium без написания кода. В этой части мы рассмотрим более тонкие вопросы работы с Selenium:
Все новые инструменты, описанные в первой части, на самом деле являются умными легковесными прокси, которые перенаправляют запросы пользователей в настоящие Selenium хабы и ноды. Если немного поразмышлять, то появляются вопросы:
Одним из способов может быть использование "железа" с одним Selenium хабом и множеством нод с различными браузерами. Выглядит разумно, но на самом деле неудобно:
Наиболее простой способ иметь одинаковое количество нод на один хаб — это запускать их внутри одной виртуальной машины. Если каждая версия браузера — это отдельная виртуальная машины, то подсчет общего числа доступных браузеров становится задачей из начальной школы. Можно легко добавлять и удалять виртуальные машины, содержащие совместимые версии ноды и браузера. Мы рекомендуем такой подход при установке кластера Selenium в облако с постоянно доступным количеством каждой версии браузера.
Что же еще кроме Selenium хаба и ноды находится внутри виртуальной машины, чтобы все работало?
Виртуальные машины не имеют монитора, поэтому Selenium должен быть запущен в особой версии X-сервера, которая эмулирует дисплей. Эта реализация называется Xvfb [5]. Запускается это так:
xvfb-run -l -a -s '-screen 0 1600x1200x24 -noreset'
java -jar /path/to/selenium-server-standalone.jar -role node <...другие аргументы>
Обратите внимание, что Xvfb нужно только для процесса Selenium-ноды.
#!/bin/bash
apt-get -y install linux-sound-base libasound2-dev alsa-utils alsa-oss
apt-get -y install --reinstall linux-image-extra-`uname -r`
modprobe snd-dummy
if ! grep -Fxq "snd-dummy" /etc/modules; then
echo "snd-dummy" >> /etc/modules
fi
adduser $(whoami) audio
Как вы уже могли заметить, Selenium — это Java-приложение. Для запуска Selenium нужно установить Java Virtual Machine (JVM). Самый маленький установочный пакет Java, называемый JRE, имеет размер около 50 мегабайт. Selenium JAR самой последней версии 3.0.1 добавляет еще 20 мегабайт. Теперь добавим размер операционной системы, нужные шрифты, размер самого браузера и вы легко достигаете нескольких сотен мегабайт. И хотя жесткие диски сейчас стоят дешево, мы можем сделать лучше. Selenium версий 2.0 и 3.0 также называют Selenium Webdriver. Это связано с тем, что поддержка разных браузеров реализована при помощи отдельных приложений, называемых веб-драйверами.
Вот как это работает:
Теперь, когда мы выяснили это, встает вопрос: не слишком ли дорого тратить сотни мегабайт для простого проксирования? Год назад ответ был определенно нет, потому что не существовало приложения-драйвера для Firefox — наиболее часто используемый браузер в Selenium. Ответственностью Selenium было запустить Firefox, загрузить в него специальное расширение и проксировать запросы в порт, открытый этим расширением. За последний год ситуация изменилась. Начиная с Firefox 48.0 Selenium взаимодействует с браузером, используя отдельный бинарный драйвер — Geckodriver [9]. Это означает, что теперь для большинства настольных браузеров мы можем совсем удалить Selenium Server и проксировать запросы напрямую в драйверы.
В предыдущих разделах я описал как можно построить кластер Selenium, используя виртуальные машины в облаке. В этом подходе виртуальные машины всегда запущены и постоянно тратят ваши деньги. Кроме того общее число доступных браузеров для каждой версии ограничено и может приводить к полному исчерпанию доступных браузеров во время пиковых нагрузок. Я слышал о работающих и даже запатентованных сложных решениях, которые запускают и прогревают пул виртуальных машин в зависимости от текущей нагрузки, чтобы всегда иметь доступные браузеры. Это работает, но можно ли сделать лучше? Основная проблема гипервизорной виртуализации — это скорость. Запуск новой виртуальной машины может занимать неколько минут. Но давайте немного подумаем — нужна ли нам отдельная операционная система для каждого браузера? — Нет, нужна только простая изоляция по диску и сети. Вот почему контейнерная виртуализация становится актуальной. На данный момент контейнеры работают в основном только под Linux, но, как я уже говорил, Linux покрывает 80% наиболее популярных браузеров. Контейнеры с браузерами стартуют за секунды и останавливаются еще быстрее.
Что же должно быть внутри контейнера? — Практически то же самое, что и внутри виртуальной машины: сам браузер, шрифты, Xvfb. Для старых версий Firefox (< 48.0) по-прежнему нужно установить Java и Selenium Server, но для Chrome, Opera и свежих версий Firefox мы можем использовать приложение-драйвер в качестве основного процесса контейнера. Если использовать легковесный Linux дистрибутив (например, Alpine), можно получить очень маленькие и легковесные контейнеры.
На данный момент наиболее популярной и известной контейнерной платформой является Docker [10]. Разработчики Selenium предоставляют набор готовых Docker контейнеров для запуска Selenium в режиме Standalone или Grid в Docker. Для того, чтобы запустить кластер из таких образов, нужно запускать и останавливать контейнеры вручную или при помощи инструментов наподобие Docker Compose [11]. Такой подход уже намного лучше, чем установка Selenium из пакетов, но было бы еще лучше, если бы существовал сервер со следующим поведением:
Мы сделали такой демон… и даже больше.
За годы использования Selenium server в больших масштабах мы поняли, что очень неэффективно использовать JVM и "толстый" Selenium JAR для простого проксирования запросов. Поэтому мы искали более легковесную технологию. Наш выбор остановился на языке программирования Go [12] также известном как Golang. Почему для наших целей Go подходит лучше?
Мы так и не придумали хорошего имени для описанного выше демона. Поэтому мы назвали его просто Selenoid [13]. Чтобы попробовать Selenoid нужно выполнить 3 простых шага:
{
"firefox": {
"default": "latest",
"versions": {
"49.0": {
"image": "selenoid/firefox:49.0",
"port": "4444"
},
"latest": {
"image": "selenoid/firefox:latest",
"port": "4444"
}
}
},
"chrome": {
"default": "54.0",
"versions": {
"54.0": {
"image": "selenoid/chrome:54.0",
"port": "4444"
}
}
}
}
Как и в XML файле для Gridrouter указан список доступных версий браузеров. Поскольку Selenoid запускает контейнеры на той же машине или через Docker API, нет необходимости указывать имена хостов и регионы. Для каждой версии браузера нужно указать имя контейнера, его версию и порт, на котором слушает основной процесс контейнера.
$ selenoid -limit 10 -conf /etc/selenoid/browsers.json
По-умолчанию Selenoid стартует на порту 4444, как обычный Selenium хаб.
Наши эксперименты показывают, что даже контейнеры со стандартным Selenium сервером внутри стартуют за несколько секунд. Взамен вы получаете гарантированное состояние диска и памяти. Браузер всегда находится в состоянии как после установки на чистую операционную систему. Кроме того вы можете установить Selenoid на большой кластер из хостов имеющих одинаковый набор поддерживаемых браузеров, сохраненных в виде Docker образов. Это дает вам большой кластер Selenium, который автоматически масштабируется в зависимости от потребления браузеров. Например, если текущие запросы пользователей требуют больше Chrome — автоматически запускается больше контейнеров. Когда запросов на Chrome не поступает — контейнеры с Chrome останавливаются и освободившиеся хосты могут использоваться для других браузеров.
Чтобы обеспечить лучшее распределение нагрузки по кластеру, Selenoid ограничивает общее число параллельных сессий на хосте и ставит в очередь все превышающие лимит запросы. Запросы из очереди обрабатываются по мере того, как завершаются более ранние сессии на том же хосте.
Но Selenoid позволяет запускать не только контейнеры. Он также умеет запускать по требованию процессы веб-драйвера. Основное применение этой функциональности — замена Selenium Server на Windows. В этом случае Selenoid стартует процесс IEDriverServer, что позволяет экономить память и избегать ошибок проксирования в самом Selenium.
Возможно, вы помните, что оригинальный GridRouter [14] — это Java приложение. Мы написали с нуля легковесную реализацию этого прокси на Go и назвали просто Go Grid Router [15] (или ggr). В чем преимущества новой версии по сравнению со старой?
В связке с Selenoid, позволяет создавать масштабируемый, надежный кластер Selenium:
В этой части я рассказал о самых последних технологиях, которые могут быть использованы для организации современного кластера Selenium:
В заключение в одном месте собраны ссылки на упомянутые в статье продукты:
Автор: aandryashin
Источник [18]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/open-source/246785
Ссылки в тексте:
[1] часть 1: https://hackernoon.com/selenium-testing-a-new-hope-7fa87a501ee9#.wn7h2t50g
[2] часть 2: https://hackernoon.com/selenium-testing-a-new-hope-a00649cdb100#.sal3gqw7y
[3] посте: https://habrahabr.ru/company/yandex/blog/268309/
[4] Appium: http://github.com/appium/appium/
[5] Xvfb: https://www.x.org/releases/X11R7.6/doc/man/man1/Xvfb.1.xhtml
[6] Microsoft True Type fonts: http://askubuntu.com/questions/578057/installation-of-fonts-in-ubuntu-14-04
[7] Chromedriver: https://sites.google.com/a/chromium.org/chromedriver/
[8] OperaDriver: https://github.com/operasoftware/operachromiumdriver
[9] Geckodriver: https://github.com/mozilla/geckodriver
[10] Docker: https://www.docker.com/
[11] Docker Compose: https://docs.docker.com/compose/
[12] Go: http://golang.org/
[13] Selenoid: http://github.com/aandryashin/selenoid
[14] GridRouter: https://github.com/seleniumkit/gridrouter
[15] Go Grid Router: https://github.com/aandryashin/ggr
[16] htpasswd: https://httpd.apache.org/docs/2.4/misc/password_encryptions.html
[17] Selenoid: https://github.com/aandryashin/selenoid
[18] Источник: https://habrahabr.ru/post/322742/?utm_source=habrahabr&utm_medium=rss&utm_campaign=best
Нажмите здесь для печати.