Erlang in Wargaming

12 июля 2016

С этой темой я выступал на митапе Func By в марте 2016

Язык Erlang известен не очень широко. Это довольно интересная технология, очень сильная в своей нише. А последние десять лет занимает какое-то место и нише веб-разработки.

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

У нас в компании Wargaming Erlang применяется больше 3-х лет. Есть около десятка разработчиков и несколько проектов, работающих под большими нагрузками.

И мы хотим поделиться своим опытом, и тем, как мы видим Erlang.

Как все началось

В Wargaming используется микросервисная архитектура, где разные сервисы взаимодействуют между собой как по HTTP-протоколу, так и по AMQP. Мы активно используем сервера RabbitMQ.

Можно сказать, с RabbitMQ и началось присутствие Erlang. И хотя программисты о нем пока еще не знали, но архитекторы и DevOps уже набирали свой опыт, разбираясь, почему где-то упал RabbitMQ, что можно извлечь из его логов и crash dump; и что нужно сделать, чтобы он не падал :)

Надо сказать, что наши архитекторы давно питали симпатии к Erlang, но не внедряли его, как язык разработки, пока не появились веские причины для этого.

Не секрет, что игровые сервера работают на движке Big World, где игровая логика пишется на Python. (Кстати, Python был и остается основным языком разработки в компании.) Изначально через эти сервера работал и внутри-игровой чат. Но было жалко тратить ресурсы игровых серверов на чат, так как их не хватало самим играм. Появилось логичное желание вынести чат на отдельный сервер.

Чат тесто связан с игрой и имеет много функциональности, специфичной для игры, поэтому было необходимо собственное решение. И, конечно, необходимо кластерное решение, так как один сервер нельзя масштабировать под имеющиеся и планируемые в будущем нагрузки. Вполне логично, что для такого проекта был выбран Erlang, и в компании появился первый Erlang разработчик.

Как все продолжалось

Помимо игровых серверов у нас есть и веб. Это и портал для игроков, и внутренние веб-сервисы. Изначально весь веб был написан на Python/Django. Не удивительно, что с быстрым ростом числа игроков в вебе начались проблемы.

Мы начали использовать Twisted. Но и разработчики, и архитекторы считали его слишком сложным, а разработку на нем слишком дорогой.

Архитекторы предлагали использовать Erlang, но менеджеры сопротивлялись. Это чату хватит трех разработчиков, а для веба разработчиков нужно много. Где же их взять?

Между тем, прототипы, написанные на Erlang, показывали хорошую производительность в бенчмарках. А Twisted продолжал причинять боль разработчикам. И архитекторы пошли дальше прототипов, сделали и запустили один небольшой веб-сервис на Erlang. Сервис был написан за пару недель усилиями одного архитектора. И оказался удачным.

Потом был второй проект, и третий. Оказалось, что на рынке труда есть Erlang разработчики. И что Python разработчики без труда осваивают Erlang. И некоторым это показалось даже проще, чем освоить Twisted.

На сегодняшний день в компании есть десяток разработчиков, которых можно назвать Erlang программистами. То есть, они большую часть кода, или даже весь свой код пишут на Erlang. Некоторые из них имеют несколько лет опыта с Erlang, а некоторые еще недавно писали на Python.

Работы у нас в вебе много. Растет количество игр, которые выпускает Wargaming. Нужно переходить от специализированных для конкретной игры сервисов, к сервисам универсальным. Поэтому стартуют новые проекты, в том числе проекты на Erlang. В своих вакансиях мы по-привычке ищем Python разработчиков, но уже упоминаем, что знание Erlang будет плюсом :)

Нам удалось привлечь сильных Erlang разработчиков. Среди них, например, Сергей Прохоров, чей патч приняла команда Erlang/OTP. Так что теперь в виртуальной машине Erlang есть немного кода Сергея.

Мнения разработчиков

Имея внутри компании достаточно много разработчиков с разным опытом, можно собрать широкий спектр мнений об Erlang. Любопытно также отметить разницу в восприятии языка между опытными и начинающими разработчикам.

Опытные в целом относятся к Erlang позитивно. И это не удивительно, иначе они бы не писали на нем несколько лет, и не стали бы опытными :)

Начинающие относятся по-разному. У них больше критики и недовольства. Это тоже не удивительно, потому что в сравнении с Python, Erlang заметно беднее и по выразительности, и по инфраструктуре, и по богатству библиотек.

Начнем с общих моментов, с которыми согласны все наши разработчики:

1. Erlang показывает хорошую производительность в вебе, измеряемую числом запросов в секунду. Добиться аналогичной производительности на Python дольше, сложнее и дороже.

2. Erlang язык узкоспециализированный. Не стоит пытаться решать на нем любые задачи.

Плюсы Erlang, общее мнение

1. Хорошая модель многопоточности, которой удобно пользоваться. Модель акторов и асинхронность позволяют легко писать эффективный многопоточный код.

2. За 20 лет использования в нагруженных проектах сформировались стандарты и шаблоны, собранные в OTP-фреймворк. С ними проще строить сложные, но стабильные и надежные системы.

3. Erlang умеет использовать все доступные ядра. Нет необходимости запускать отдельный экземпляр сервиса для каждого ядра.

4. Низкий порог вхождения. Язык простой, изучается быстро. (Однако, тут есть некоторые подводные камни, о чем будет написано ниже).

Плюсы, которые видят начинающие разработчики

1. Замкнутая экосистема, проекту не нужно ничего из внешнего мира.

2. Не нужно внешнее in-memory хранилище (Radis, memchached), можно держать кэш прямо в оперативной памяти сервиса.

3. Не нужно запускать несколько экземпляров сервиса для каждого ядра, под внешним супервизором, со своей конфигурацией. Один сервис может использовать все ядра, и имеет свою гибкую систему супервизоров.

4. Меньше экземпляров сервисов – меньше общения между ними по HTTP или AMQP. Гораздо удобнее общаться между процессами внутри одного узла.

5. Проще разрабатывать распределенные системы. У Erlang есть свои средства для построения кластеров и общения между узлами.

Плюсы, которые видят опытные разработчики

1. Функциональная парадигма, иммутабельные структуры данных.

2. Удобно мониторить сервис в реальном времени, искать и устранять проблемы прямо на работающем узле.

3. Можно менять конфигурацию без перегрузки сервиса.

Минусы, общее мнение

1. Мало библиотек, еще меньше библиотек хорошего качества. Многое нужно писать самим или дорабатывать.

2. Ограниченный синтаксис языка, иногда не хватает более удобных синтаксических конструкций. Например, не помешала бы конструкция let, чтобы вводить области видимости. Докучает необходимость создавать переменные с числовыми суффиксами: Var1, Var2, Var3.

3. Язык консервативный и развивается очень медленно. Например, тип map внедряли несколько лет (и еще до конца еще не доделали).

4. Медленно развивается инфраструктура для веба, нет веб-фреймворка. Язык ориентирован на более низкоуровневое применение, чем то, что привычно Python/Django или Ruby/Rails разработчику.

Минусы, которые видят начинающие разработчики

1. Строки реализованы ужасно, средств для работы со строками очень мало. (Опытные разработчики вообще строками не пользуются, и поэтому забыли про такую проблему :)

2. Слабая стандартная библиотека, мало возможностей. Это особенно заметно на фоне Python. Несогласованности в стандартных модулях (названия функций, порядок аргументов, возвращаемые значения).

3. Функциональная парадигма, иммутабельные структуры данных. Что для опытного разработчика плюс, для начинающего, не знакомого с парадигмой – минус. Это требует отдельного изучения.

4. Тяжело читать сообщения об ошибках.

Минусы, которые видят опытные разработчики

1. Нет хороших инструментов для управления зависимостями и сборки пакетов. rebar3 и hex – движение в нужную сторону, но они еще сырые и не приняты широко.

2. Релизы устроены сложно и решают не те задачи. Например, они решают задачу горячего обновления, а это не нужно веб-разработчику. Правильнее строить сервис так, чтобы он безболезненно переживал остановку одного узла.

3. Синтаксис конфигов не удобен DevOps. Честно говоря, он не удобен и самим разработчикам. Лучше описывать конфигурацию в более простых форматах, например, ini.

Еще несколько индивидуальных мнений

1. Python разработчику проще освоить Erlang, чем Twisted, не смотря на то, что это совсем другой язык. Проекты на Erlang проще, разрабатываются быстрее, и ведут себя надежнее, чем аналогичные проекты на Twisted.

2. Сообщество Erlang разработчиков маленькое и не очень активное. Разработчики живут каждый в своих компаниях и проектах, мало общаются друг с другом. Обычная ситуация, что каждый разработчик пишет свой набор библиотек, который используется только в его проекте.

3. Есть крупные open source проекты, как Cowboy или Riak, но нет проектов, вокруг которых сложилось бы активное сообщество.

4. Виртуальная машина Erlang хорошая, а сам по себе язык – слишком консервативный, не стремится к развитию. Поэтому активное развитие сейчас идет в рамках новых языков для этой виртуальной машины, как, например, Elixir.

5. Erlang и Python неплохо дополняют друг друга, компенсируют слабые стороны друг друга. Поэтому правильно сочетать их вместе в одном проекте. Бизнес-логику, ORM, работу с базой лучше делать на Python, а многопоточную обработку данных, связь между сервисами, фоновые процессы – на Erlang.

6. Erlang обладает ужасным синтаксисом, который заставляет страдать :)

Что получается в сухом остатке?

В целом разработчики с удовольствием критиковали Erlang, и минусов находили побольше, чем плюсов. Это не удивительно, ведь к достоинствам технологии быстро привыкаешь и считаешь их само-собой разумеющимся, а к недостаткам привыкаешь меньше, и они продолжают раздражать и привлекать внимание.

Однако, у нас разработчики сами выбирают язык для своих проектов (конечно, из списка одобренных архитекторами :), это решение не навязывается сверху. И раз уж разработчики выбирают Erlang, значит он не так плох :)

На сегодняшний день в нашем вебе используются Python 2.7, Python 3.5 и Erlang. Архитекторы не против разрешить кому-то попробовать и другие варианты: язык Go, какой-нибудь из JVM языков, еще что-то – но пока желающие не нашлось. А нашлись желающие попробовать Elixir, и об этом будет ниже.

Коварный порог входа

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

Это правда, но не вся правда. Язык действительно простой и легко изучается, и через 2 недели можно писать код для продакшена. Но потом-то и появляются подводные камни.

Во-первых, есть детские проблемы, на которых многие неопытные разработчики спотыкаются, а опытные, научившись их решать, про них забывают. Классическая такая проблема – получить deadlock в gen_server. Это случается почти у всех. Своего рода ритуал вхождения в клуб разработчиков :)

Вторая такая проблема – понять, что строками пользоваться не нужно, а нужно везде использовать binary. Этого правила легко придерживаться в своем проекте. К сожалению, в сторонних библиотеках может быть по-всякому, и к этому нужно быть готовым.

Но есть проблемы не детские. И первая из таких проблем – недостаток информации. По Erlang написано несколько хороших книг. Большинство из них описывают язык как таковой, а не применение его для решения прикладных задач. Многие важные вопросы не описаны в книгах и в документации.

Какие инструменты использовать для сборки проекта? Как мониторить работающий узел? Как обнаружить переполнение mailbox? А другие варианты утечки памяти? Как находить узкие места, мешающие масштабировать систему? Об этом можно узнать только от другого опытного разработчика.

Какие библиотеки использовать? Их, с одной стороны, мало. С другой стороны, популярные библиотеки имеют много форков. И не понятно, что это за форки, чем отличаются, как поддерживаются. Те, кто искал драйвер для работы с MySQL, хорошо понимают эту проблему :)

И это мы еще не взялись за распределенные системы – отдельный мир с кучей своих нюансов.

Поэтому важно иметь в команде опытных разработчиков.

Несколько слов про Elixir

Существует несколько языков, которые компилируются в байт-код Erlang и работают на виртуальной машине Erlang. Самый популярный из них – Elixir.

Несколько лет назад на Erlang обратили внимание Ruby/Rails разработчики. Они искали решение проблем с производительностью, характерных для Rails. Проблемы с производительностью решились, но все остальное в Erlang этим разработчикам не понравилось. И не удивительно, из мощного высокоуровневого языка с богатейшей инфраструктурой они попали в суровый низкоуровневый мир.

Эти разработчики быстро поняли, что так жить они не хотят, и начали строить для себя более комфортную среду. Результатом их усилий стали язык Elixir, веб-фреймворк Phoenix и активное сообщество вокруг них. За 3 года они сделали больше для веб-разработки, чем в Erlang было сделано за 10 лет.

Об Elixir, как и об Erlang, есть противоречивые мнения.

Одни считают его легко читаемым, лаконичным и мощным. Другие считают язык сложно читаемым и непродуманным. Консервативные Erlang разработчики в основном относятся к Elixir прохладно. А разработчики, пришедшие в Erlang из Ruby или Python, принимают Elixir с любопытством.

Плюсы языка:

Минусы:

Сообщество занято инфраструктурой, библиотеками и фреймворком, а ядро языка разрабатывается небольшой командой. Есть риск, что если эта команда потеряет финансирование, и ее никто не заменит, то язык перестанет развиваться и поддерживаться.

У нас в вебе Wargaming прототип одного из будущих сервисов делают на Elixir. Посмотрим, как он себя покажет.

comments powered by Disqus