Распределенный Erlang? Вероятно, вам это не нужно!

26 августа 2013

Возможность Erlang‘а производить прозрачный обмен сообщениями между процессами, работающими на разных физических машинах, бесспорно, является интересной и порой весьма практичной. Но не факт, что эту возможность следует использовать именно в вашем проекте. Хотя далее по тексту речь будет идти об Erlang, многое из написанного также относится и к распределенным акторам в Akka или Cloud Haskell.

Дополнение: При использовании Akka Cluster, как выяснилось, возникают очень похожие проблемы. Также приходится дополнительно помнить о том, как ведет себя система в разных граничных случаях (какие гарантии на доставку сообщений по сети? что происходит при смерти синглтона?); постоянно думать об обратной совместимости сообщений, передаваемых между акторами; намного сложнее становятся тестирование и бесшовная раскладка, приходится дополнительно следить, чтобы кластер не разваливался, что особенно часто случается в сети AWS; если одному актору стало плохо, например, выросла большая очередь сообщений, страдает не одна машина, а весь кластер; ну и так далее.

Для определенности скажем, что вы разрабатываете на языке Erlang высоконагруженное веб-приложение, которое должно взаимодействовать с другими приложениями, также написанными вами на Erlang. Нужно выбрать, использовать обмен сообщениями, или же осуществлять взаимодействие между приложениями с помощью REST API (так называемая сервис-ориентированная архитектура или SOA).

Вот некоторые причины, почему стоит сделать выбор в пользу REST:

  • Помимо команды матерых Erlang-программистов, занимающейся непосредственно разработкой приложения, есть и другие заинтересованные лица. Это админы, тестировщики, недавно прибывшие в команду джуниоры и программисты из соседних отделов, использующие другие языки. Все эти люди не понимают, как работать с распределенным Erlang’ом и для чего нужны эти дуратские куки;
  • Вашему приложению рано или поздно придется взаимодействовать с программами, написанными на языках, отличных от Erlang, для чего, видимо, все равно придется предусмотреть REST API. Зачем поддерживать два интерфейса, если можно сразу сосредоточить свои усилия на одном? HTTP — наиболее универсальное решение, с ним можно работать на любом нормальном языке;
  • Распределенный Erlang — это зияющая дыра в безопасности. Когда в вашу систему попадет злобный хакер и украдет Erlang’овую куку, он автоматически получит доступ ко всем машинам, на котором работают ноды, использующие эту куку;
  • Практически все программисты прекрасно понимают, как работать с REST API. Однако использование в проекте распределенных процессов потребует от программистов изучения целого нового фреймворка со всеми его особенностями и подводными граблями. Если процесс умер, будут ли доставлены все отправленные им сообщения? Каковы гарантии на доставку сообщений в случае временного падения сети? (Правильные ответы содержатся, например, в книге Erlang and OTP in Action);
  • При использовании распределенных процессов вас ждут целые классы новых увлекательных ошибок. Например, возникающих в результате использования разных версий некой библиотеки или виртуальной машины Erlang’а на разных нодах, netsplit’ов, залипания epmd или конфликтов глобальных имен. Хуже всего то, что эти ошибки часто возникают не по вине программистов. Например, админы могут перенести приложение на новый сервер, а спустя какое-то время ребутнуть старый сервер, на котором автоматически запуститься старая версия приложения, что приведет к массе занятных эффектов;
  • При использовании распределенных процессов ваш код становится более запутанным. Уже нельзя с уверенностью сказать, кто, куда и зачем ходит. В случае использования HTTP все намного проще, потому что адреса сервисов должны указываться в конфиге приложения, а хождение в них осуществляться через библиотеки для работы с HTTP;
  • Использование распределенных процессов может лишний раз препятствовать горизонтальному масштабированию. В общем случае вы уже не можете просто взять и запустить еще один экземпляр приложения, хотя бы, потому что это может привести к конфликту глобальных имен;
  • Для работы с HTTP имеется куча готовых библиотек, а также проксей, позволяющих настроить gzip’ование и шифрование трафика, всевозможных сниферов и так далее. При использовании HTTP в ваше приложение можно будет ходить из кода на JavaScript, что позволит без труда писать всякие там веб-админки и прочее. Любой грамотный админ с легкостью настроит вам балансировку нагрузки хотя бы с помощью того же DNS. Отладка и тестирование станут существенно проще;

Понятно, что все зависит от конкретной ситуации. Если вам нужно, например, обрабатывать сто тысяч котировок в секунду, то передавать их по HTTP в JSON’е может оказаться не самой лучшей идеей. Однако если вы пишите приложение, которое обменивается с другими приложениями сравнительно небольшими объемами данных, желание поиграться с распределенными процессами в Erlang, Cloud Haskell или Akka, скорее всего, не принесет вам ничего, кроме боли и глубокого разочарования.

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

В общем, что касается распределенных процессов в Erlang — скорее всего, вы не должны этого хотеть.

Метки: , .

Подпишись через RSS, E-Mail, Google+, Facebook, Vk или Twitter!

Понравился пост? Поделись с другими: