Выбор хостинга под Эликсир
Эликсир предоставляет мощные встроенные инструменты вроде Редиса или Кубернейтса, которые в некоторых случаях могут заменить эти внешние зависимости. При этом, есть три области, требующие осторожности:
- хранение состояния в памяти;
- масштабируемость;
- горячее обновление кода.
Три мощных идеи со своими неприятными особенностями, стоимости использования которых стоит уделить должное внимание.
Хранение состояния в памяти
Для управления состоянием сервиса, разработчики нередко прибегают к помощи таких хранилищ, как Редис или Постгрес. Избежать подобных зависимостей иногда под силу следующим встроенным инструментам Эликсира:
Это добавляет разработчикам некой гибкости, позволяя обращаться к зависимостям только тогда, когда это необходимо. Однако если состояние хранится в памяти приложения, возникает спорная ситуация: с одной стороны, задержка при взаимодействии с данными уменьшается, но если содержащий состояние процесс умирает, то состояние умирает вместе с ним. Если в качестве хоста используется AWS EC2, такие ситуации редки, и их возникновение будет в основном обусловлено частотой возникновения критических ошибок. При использовании Хероку с перезапусками «серверных контейнеров» это будет происходить как минимум ежедневно.
Важно отметить, что вариант с Хероку всё равно имеет место быть. Имеет смысл хотя бы предположить, что драгоценные хранящие состояние процессы потерпят крах, потому что рано или поздно это случится, каким бы длительным ни было время безотказной работы приложения. Такова правда, и она должна натолкнуть вас на принятие важных архитектурных решений как можно скорее (читай: прежде чем приступать к основной разработке). Как минимум, задайтесь следующими вопросами о состоянии, которым будет управлять сервис.
Насколько данные моего приложения:
- временные?
- несущественные?
- восстанавливаемые быстро и без особых затрат?
В зависимости от ответов на данные вопросы и конкретного случая, можно обойтись и теми средствами, которые предлагает Эликсир — сбрасывать состояние или управлять им только в случае гибели процесса и восстанавливать согласованное состояние, когда они возвращаются к жизни. С другой стороны, если важное состояние хранится в памяти, восстановление которой затратно и занимает продолжительное время, а родительский процесс умирает, то клиентам такого сервиса придётся непросто. Если в приоритете уменьшение времени задержки, а не избавление от зависимости, отличным выбором станет Редис. Его можно использовать как самостоятельно, так и в качестве кэша со сквозным чтением поверх Постгреса.
Масштабируемость
Несмотря на то, что Эликсир способствует созданию масштабируемых распределённых сервисов, не стоит забывать что бесплатный сыр — только в мышеловке. Эликсир будет масштабироваться вертикально, пока всё ядро не будет полностью задействовано, а затем — масштабировать ядра горизонтально, но что дальше? Горизонтальное масштабирование нескольких машин и объединение нод из этих машин в кластеры — это не одно и то же.
Масштабируя в рамках нескольких машин, не объединяя ноды в кластеры, вы зададите себе ряд вопросов. Как нужно масштабировать сервис? Нормально ли, что требуется делать это вручную? Как быстро я смогу это с этим справиться? Во сколько мне это обойдется? Как правило, провайдеры, выполняющие большее количество работы за вас и упрощающие разработку и эксплуатацию априори будут стоить дороже, и цена возрастёт при масштабировании. В свою очередь, если вы уже инвестировали время и знания в проект, вполне подойдёт провайдер с более узким спектром услуг, который, разумеется, будет дешевле.
Если существует необходимость создания кластеров, использование провайдеров без внутренних частных сетей, в частности Хероку, невозможно. Однако это правило применимо далеко не во всех случаях, да и не каждому сервису необходимы кластеры для масштабирования.
Горячее обновление кода
Горячее обновление кода — способность обновления уже запущенного релиза до новой версии без простоя. Это очень мощная функция, которой не стоит увлекаться. Будет даже правильнее сказать, пользоваться только в случае крайней необходимости, при этом не обойтись без продолжительного и тщательного планирования. Если форма состояния изменилась в системе повсеместно, её необходимо передать через функцию, которая аккуратно поменяет старую форму на новую. Тестированию обновления следует уделять не меньше времени, чем тестированию целой системы.
В добавок, горячее обновление кода противоречит одному из лучших актуальных подходов в разработке и развертывании, а именно контейнеризации. Рекомендуется создавать релизы в контейнерах, похожих на то, что будет в продакшене. Помимо этого, с появлением таких сервисов, как AWS ECS и Кубернейтс, подобная практика с контейнерами стала ещё более широко распространённой. Среди главных её преимуществ — концепция иммутабельных релизов и среда разработки, очень напоминающая продакшн. Релиз новой версии через горячее обновление кода с помощью контейнеров в теории возможен, но на практике такой подход перечеркнёт идею иммутабельности и добавит сложности проекту — будет сложно разобраться что и где развернуто и убедиться, что незапланированные перезапуски системы выдадут корректную версию сервиса.
Из-за присущей сложности и несогласованности в работе с контейнерами рекомендуется воздержаться от применения горячего обновления кода, насколько это возможно. В большинстве случаев это достаточно просто, особенно при использовании таких подходов, как последовательное обновление или сине-зеленый деплой для достижения адекватного уровня доступности до, после и во время развертывания новой версии.
Если исключительная особенность сервиса заключается в том, чтобы у него не было простоя, состояние хранилось в памяти приложения и он будет неспособен истощить ноды, то горячее обновление кода отлично подойдёт. Часто в таких ситуациях разработчики останавливают свой выбор на AWS EC2 или других облачных провайдерах. В общем, требования таковы:
- Никаких контейнеров.
- Машина, находящаяся под полным контролем команды разработчиков.
- Масштабный проверенный в действии провайдер с впечатляющими гарантиями времени безотказной работы и достаточным набором сопутствующих функций, позволяющих в будущем не усомниться в выборе.
Поставив галочку напротив каждого пункта выше, можно быть уверенным, что горячее обновление кода обеспечит поразительные временные показатели и быстрое обновление, так как истощение ресурсов ноды не произойдёт. Но будьте готовы к большему количеству ручных доработок в девопсе и усиленным подготовкам к новым релизам.
Выводы
Выбирая провайдера, обратите внимание на следующие параметры:
- размер: проверенный на практике, гарантирующий качество;
- ключевые характеристики: время безотказной работы, сторонние сервисы и наличие внутренних частных сетей;
- сложность: количество девопс-задач;
- стоимость: соотношение цена/качество.
Оцените вышеизложенные параметры в отношение Эликсира, акцентируя внимание на:
- хранение состояния в памяти;
- масштабируемость;
- горячее обновление кода.
API Эликсира с Фениксом прямолинейны и не хранят состояние, поэтому здесь подойдут почти все провайдеры, при условии если ожидания по трафику и стоимость масштабирования учтены. Если сервису понадобится хранить состояние или он начнёт планомерно усложняться, стоит уделить больше внимания требованиям. Если вы запускаете несколько сервисов сразу, можно сэкономить, выбрав для разных целей один хост, которому под силу справиться как с простыми, так и со сложными задачами. Конечно, два разных сервиса не могут иметь одни и те же требования, но этап тщательного планирования, к которому можно прибегать неоднократно, позволит увеличить эффективность ваших приложений.