Компания
962,39
рейтинг
19 сентября 2014 в 12:58

Разработка → Centrifuge — я больше не буду обновлять страницу перед отправкой комментария

Прошло некоторое время с тех пор, как я писал про Центрифугу в предыдущий раз. Произошло множество изменений за этот период. Многое из того, что было описано в ранних статьях (1, 2) кануло в лету, но суть и идея проекта остались прежними — это сервер рассылки real-time сообщений пользователям, подключенным из веб-браузера. Когда на вашем сайте возникает событие, о котором вам нужно моментально сообщить некоторым вашим пользователям, вы постите это событие в Центрифугу, а она, в свою очередь, отправляет его всем заинтересованным пользователям, подписанным на нужный канал. В самом простом виде это показано на схеме:



Проект написан на Python с использованием асинхронного веб-сервера Tornado. Использовать можно даже если бекенд вашего сайта написан не на Python. Хотелось бы рассказать о том, что Центрифуга представляет собой на данный момент.



Попробовать проект в действии совсем несложно, если вы знакомы с установкой Python-пакетов. Внутри virtualenv:

$ pip install centrifuge

Запуск:

$ centrifuge

После этого по адресу http://localhost:8000 будет доступен административный интерфейс процесса Центрифуги, который вы только что запустили.

Специально для статьи я запустил инстанс Центрифуги на Heroku — habrifuge.herokuapp.com. Пароль — habrahabr. Я надеюсь на вашу честность и благоразумие — демо никак не защищено от попыток все поломать и не дать остальным оценить проект. Запущено на бесплатном дино со всеми вытекающими. Heroku, конечно, не лучшее место для хостинга такого рода приложений, но для целей демонстрации сойдет.

Думаю, я не буду далек от истины, если скажу, что аналогов Centrifuge, как минимум в open-source мире Python, нет. Попробую пояснить, почему я так считаю. Существует масса способов добавить real-time события на сайт. Из того, что приходит на ум:

  • отдельно стоящий асинхронный сервер;
  • облачный сервис (pusher.com, pubnub.com);
  • gevent (gunicorn, uwsgi);
  • модули/расширения Nginx;
  • BOSH, XMPP.

В JavaScript есть Meteor, Derby — совсем другой подход. Еще есть замечательный Faye — сервер, легко интегрирующийся с вашим JavaScript или Ruby бекендом. Но это решение для NodeJS и Ruby. Центрифуга реализует первый из перечисленных выше подход. Преимущество отдельно стоящего асинхронного сервера (и облачного сервиса) в том, что вам не нужно менять код и философию существующего бекенда, что неизбежно произойдет, как только вы, например, решите использовать Gevent, пропатчив стандартные библиотеки Python. Подход с отдельным сервером позволяет легко и безболезненно интегрировать real-time сообщения в уже существующую архитектуру бекенда.

Недостаток — на выходе при подобной архитектуре получается немного «урезанный» real-time. Ваше веб-приложение должно выдерживать HTTP запросы от клиентов, генерирующие события: новые события попадают первоначально на ваш бекенд, проходят валидацию, сохраняются в базу данных, если необходимо, и только потом отправляются в Centrifuge (в pusher.com, в pubnub.com и др.). Однако это ограничение в большинстве случаев никак не сказывается на задачах веба, от этого могут пострадать динамичные real-time игры, где один клиент генерирует очень большое количество событий. Для таких случаев, пожалуй, нужна более тесная интеграция real-time приложения и бекенда, возможно, что-то вроде gevent-socketio. Если события на сайте генерирует не клиент, а сам бекенд, то в этом случае озвученный выше недостаток роли не играет.

Говоря, что аналогов Центрифуги в open-source мире Python нет, я не имею в виду то, что нет другой реализации отдельно стоящего сервера рассылки сообщений через веб-сокеты и полифиллы к ним. Я просто не нашел ни одного подобного проекта, в полной мере из коробки решающего большинство проблем реального использования.

Набрав в поисковике "python real-time github" вы получите массу ссылок на примеры подобных серверов. Но! Большинство из этих результатов лишь демонстрируют подход к решению проблемы, не вдаваясь вглубь. Вам не хватает одного процесса и нужно как-то масштабировать приложение — хорошо, если в документации проекта будет написано, что для этих целей нужно использовать PUB/SUB брокер — Redis, ZeroMQ, RabbitMQ — это правда, но придется реализовывать это самостоятельно. Зачастую все такие примеры ограничиваются переменной класса типа set, в которую добавляются новые объекты соединений и рассылка нового сообщения всем клиентам из этого сета подключений.

Основная цель Центрифуги — из коробки предоставлять решение проблем реального использования. Давайте посмотрим на некоторые моменты, с которыми придется иметь дело подробнее.

Полифиллы

Одних вебсокетов недостаточно. Если не верите, посмотрите выступление с говорящим названием «Websuckets» от одного из разработчиков Socket.io. Вот слайды. А вот видео:



Конечно, есть проекты (опять же, динамичные real-time игры), для которых использование именно веб-сокетов — критично. Центрифуга использует SockJS для эмуляции веб-сокетов в старых браузерах. Это означает поддержку браузеров вплоть до IE7 с помощью использования таких транспортов как xhr-streaming, iframe-eventsource, iframe-htmlfile, xhr-polling, jsonp-polling. Для этого используется замечательная реализация SockJS сервера — sockjs-tornado.

Cтоит также отметить, что к Центрифуге также можно подключаться, используя «чистые» вебсокеты — без оборачивания взаимодействия в SockJS-протокол.

В репозитории есть JavaScript-клиент с простым и понятным API.

Масштабирование

Вы можете запустить несколько процессов — они будут общаться между собой, используя Redis PUB/SUB. Хотелось бы отметить, что Centrifuge совсем не претендует на инсталляцию внутри огромных сайтов с миллионами посетителей. Пожалуй, для таких проектов нужно найти другое решение — те же облачные сервисы или свои разработки. Но для подавляющего большинства проектов нескольких инстансов сервера за балансировщиком, связанных PUB/SUB механизмом Redis, будет более чем достаточно. У нас, например, один инстанс (Redis не нужен в таком случае) выдерживает 1000 одновременных подключений без проблем, среднее время отправки сообщений при этом менее 50мс.

Вот, кстати, график из Graphite за недельный период работы Центрифуги, используемой интранетом Mail.Ru Group. Синяя линия — количество активных подключений, зеленая — среднее время рассылки сообщений в миллисекундах. Посередине – выходные. :)



Аутентификация и авторизация

Подключаясь к Центрифуге, вы используете симметричное шифрование на основе секретного ключа проекта для генерации токена (HMAC). Этот токен валидируется при подключении. Также при подключении передаются ID пользователя и, по желанию, дополнительная информация о нем. Поэтому Центрифуга знает достаточно о ваших пользователях, чтобы обрабатывать подключение к приватным каналам. Этот механизм по своей сути очень похож на JWT (JSON Web Token).

Хотелось бы отметить одно из недавних нововведений. Как я рассказывал в предыдущих статьях, если клиент подписывается на приватный канал, то Центрифуга отправит POST запрос вашему приложению, спрашивая, можно ли пользователю с таким-то ID подключиться к определенному каналу. Сейчас появилась возможность создать приватный канал, при подписке на который ваше веб-приложение вообще не будет задействовано. Просто назовите канал как вам удобно и в конце после специального символа # напишите ID пользователя, которому позволено подписываться на этот канал. Только пользователю с ID 42 будет позволено подписаться на этот канал:

news#42

А еще можно делать вот так:

dialog#42,56

Это приватный канал для 2-х пользователей с ID 42 и 56.

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

Пожалуй, в процессе развития проекта было два наиболее сложных решения: как синхронизировать состояние между несколькими процессами (в итоге был выбран самый простой путь — использование Redis) и проблема с клиентами, подключившимися к Центрифуге до того, как их деактивировали (забанили, удалили) в веб-приложении.

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

Как я уже описывал раньше, для того чтобы из браузера подключиться к Центрифуге, нужно передать, помимо адреса подключения, некоторые обязательные параметры — ID текущего пользователя и ID проекта. Также в параметрах подключения должен присутствовать HMAC токен, сгенерированный на основе секретного ключа проекта на бекенде веб-приложения. Этот токен подтверждает корректность переданных клиентом параметров.

Беда в том, что раньше, единожды получив подобный токен, клиент мог без проблем пользоваться им и в будущем: подписываться на публичные каналы, читать из них сообщения. Благо не писать (так как сообщения изначально проходят через ваш бекенд)! Это для многих публичных сайтов вполне нормальная ситуация. Тем не менее, я был уверен, что дополнительный механизм защиты данных нужен.

Поэтому среди обязательных параметров при подключении появился параметр timestamp. Это Unix секунды (str(int(time.time()))). Этот timestamp также участвует в генерации токена. То есть подключение теперь выглядит вот так:

var centrifuge = new Centrifuge({
    url: 'http://localhost:8000/connection',
    token: 'TOKEN',
    project: 'PROJECT_ID',
    user: 'USER_ID',
    timestamp: '1395086390'
});

В настройках проекта появилась опция, отвечающая на вопрос: сколько секунд новое соединение должно считаться корректным? Центрифуга периодически ищет соединения, у которых истек срок действия и добавляет их в специальный список (на самом деле set) для проверки. Раз в определенный интервал времени Центрифуга отправляет POST запрос вашему приложению со списком ID пользователей, нуждающихся в проверке. Приложение в ответ отправляет список ID пользователей эту проверку не прошедших — эти клиенты будут сразу же насильно отключены от Центрифуги, при этом автоматического реконнекта на стороне клиента не будет.

Но не все так просто. Существует вероятность, что «злоумышленник», подправив, например, JavaScript на клиенте, моментально переподключится после того, как его насильно выгнали. И если timestamp в его параметрах подключения всё еще валиден — соединение будет принято. Но на следующем же цикле проверки, после того как его соединение просрочится, его ID будет по тому же механизму отправлен веб-приложению, оно скажет, что юзер невалиден, и после этого он будет отключен навсегда (так как срок действия timestamp уже истек). То есть существует небольшая щель во времени, в течение которой у клиента есть возможность продолжать читать из публичных каналов. Но её величина конфигурируется — думаю, совсем не страшно, если после фактической деактивации пользователь еще некоторое время сможет читать сообщения из каналов.

Возможно, с помощью схемы понять этот механизм будет гораздо проще:



Деплой

В репозитории есть примеры реальных конфигурационных файлов, которые используются у нас для деплоя Центрифуги. Мы запускаем ее на CentOS 6 за Nginx под супервизором (Supervisord). Есть spec-файл — если у вас CentOS, то вы можете собрать rpm на его основе.

Мониторинг

В последней версии Центрифуги появилась возможность экспортировать различные метрики в Graphite по UDP. Метрики агрегируются в заданном интервале времени, à la StatsD. Выше по тексту была как раз картинка с графиком из Graphite.

В предыдущей статье про Центрифугу я рассказывал, что в ней используется ZeroMQ. И комментарии были единодушны — ZeroMQ не нужен, используй Redis, производительности которого хватит с головой. Сначала я немного подумал и добавил Redis в качестве опционального PUB/SUB бекенда. А потом был вот этот бенчмарк:



Я был удивлен, правда. Почему ZeroMQ оказался настолько хуже для моих задач, чем Redis? Я не знаю ответа на этот вопрос. Поискав в интернете, нашел статью, где автор также сетует на то, что ZeroMQ для быстрого real-time веба подходит плохо. К сожалению, сейчас уже потерял ссылку на эту статью. В итоге — ZeroMQ в Центрифуге уже не используется, осталось только 2 так называемых engine-а — Memory и Redis (первый подойдет, если вы запускаете один инстанс Центрифуги, и вам ни к чему Redis и его PUB/SUB).

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

Из других изменений:

  • MIT лицензия вместо BSD;
  • рефакторинг неймспейсов: теперь это не отдельная сущность и поле в протоколе, а просто префикс в имени канала, отделенный двоеточием (public:news);
  • улучшения в JavaScript-клиенте;
  • работа с JSON теперь может быть значительно ускорена, если дополнительно установить модуль ujson;
  • организация Centrifugal на GitHub — с репозиториями, имеющими отношение к проекту, помимо Python-клиента для Центрифуги — там сейчас в том числе есть пример как развернуть проект на Heroku и первая версия библиотеки adjacent — небольшая обертка для интеграции с Django (упрощает жизнь с генерацией параметров подключения, есть методы для удобной отправки сообщений в Центрифугу);
  • поправлена/расширена документация в соответствии с изменениями/добавлениями;
  • множество других изменений отражены в changelog.

Как уже упоминалось ранее в блоге Mail.Ru Group на Хабре, Центрифуга используется в нашем корпоративном интранете. Real-rime сообщения добавили удобства использования, красок и динамики нашему внутреннему порталу. Пользователям не нужно обновлять страничку перед отправкой комментария (не нужно обновлять, не нужно обновлять...) — разве это не прекрасно?

Заключение

Как и любое другое решение, использовать Центрифугу нужно с умом. Это не серебряная пуля, нужно понимать, что по большому счету это лишь брокер сообщений, единственная задача которого держать соединения с клиентами и отправлять им сообщения.

Не стоит ждать гарантированной доставки сообщения клиенту. Если, например, пользователь открыл страничку, потом погрузил свой ноутбук в сон, то когда он «разбудит» свою машинку, соединение с Центрифугой вновь установится. Но все события, которые произошли, пока ноутбук находился в спящем режиме, будут потеряны. И пользователю нужно либо обновлять страничку, либо вам самостоятельно дописывать логику догрузки потерянных событий с вашего бекенда. Также нужно помнить, что практически все объекты (подключения, каналы, история сообщений) хранятся в оперативной памяти, поэтому за ее потреблением важно следить. Нужно не забывать о лимитах операционной системы на открытые файловые дескрипторы и увеличить их при необходимости. Необходимо думать о том, какой канал создать в той или иной ситуации — приватный или публичный, с историей или без, какова должна быть длина этой истории и т.д.

Как я упоминал выше, способов добавить real-time на ваш сайт — масса, выбирать нужно с умом, возможно в вашем случае более выигрышным окажется не вариант с отдельным асинхронным сервером.

P.S. В конце весны я посетил конференцию python-разработчиков в Санкт-Петербурге Piter Py. В одном из докладов зашла речь о мгновенных уведомлениях пользователей о том, что их задача, которая выполнялась асинхронно в Celery-воркере, готова. Докладчик сказал, что для этих целей они используют как раз Tornado и вебсокеты. Далее последовало несколько вопросов о том, как это работает в связке с Django, как запускается, какая авторизация… Парни, задававшие те вопросы, если вы читаете эту статью, дайте Центрифуге шанс, она замечательно подходит для подобных задач.
Автор: @FZambia

Комментарии (31)

  • +5
    Вы не поверите, у меня все еще весьма благополучно работает realplexor Дмитрия Котерова, написанный на Perl. Ем и нахваливаю) Принцип там тот же.
    • +4
      Конечно, в мире достаточно подобных проектов, более матерых и закаленных большим количеством инсталляций внутри живых проектов. Однако я вижу ценность Центрифуги в нескольких вещах. Она написана на Python на основе современных библиотек — Tornado, SockJS. Это достаточно популярные технологии и, возможно, некоторые python-программисты смогут найти решение своих проблем в коде Центрифуги, даже не используя ее по прямому назначению, — достаточно много подводных камней пришлось преодолеть на пути к тому виду, что есть сейчас. Также Центрифуга обладает некоторыми отличиями от большинства существующих решений — это уникальный механизм настроек каналов, приватные каналы для пользователей, авторизация, веб-интерфейс из коробки да и много еще чего можно назвать — так что, мне кажется, проект получился достаточно самобытным. На мой взгляд — ее действительно очень легко использовать, тем более если вы — питонист.

      Я в заключении к статье старался подчеркнуть, что я никоим образом не призываю всех подсаживаться на Центрифугу — тем более если вы уже используете нечто подобное.
    • +1
      Хотя мы тоже используем реалплексор в продакшине уже года четыре, но вот согласится, что это одно и то же, очень сложно. Все же, там только long-polling, а здесь Websocket если есть (а все же, в большинстве случаев он есть). Кроме того, в реалплексоре есть все еще сложные баги с размером сообщений (но поддается конфигурированию, хоть не очевидному). Так что в этих двух продуктах больше разного, чем общего, хотя в основе лежит базовая архитектура сообщений с бекенда в браузер.
    • 0
      Я, скорее, для ностальгии. Меня радует, но и пугает то обстоятельство, что мы используем настолько старую гвардию)
      Вашу разработку всячески приветствую и, наряду с прочими, буду рассматривать как будущую альтернативу.
  • –10
    Автор изобрел велосипед Publish/Subscribe?
    • +5
      Вообще-то нет — это просто проект, использующий принципы Publish/Subscribe. Pub/Sub — это паттерн, обвязку вокруг которого вам придется писать самостоятельно или использовать готовое решение — например, Центрифугу, Faye, тот же Realplexor
  • 0
    Подружить все это с AngularJS (или любой другой библиотекой с 2-way data binding) и сделать Q-совместимым — и настанет в мире счастье.
    • 0
      Они дружат) У меня сформировалась целая библиотека для увязки angular с комет-сервером. Причем на уровне прямого взаимодействия с апи там — минимум, сам без проблем переключал на разные технологии или даже на очередь ajax-запросов на lowload проектах, где это было оправдано. Если найдутся, кому интересно, выложу и опишу (может, новая политика Хабра простимулирует начать писать, наконец)
      • 0
        Делитесь
  • +1
    Как вы боретесь с лимитом открытых соединений в браузере пользователя? Допустим пользователь открывает несколько табов и начиная с некоторого таба в нем пропадают нотификации т.к. браузер не дает открыть новое соединение к хосту с центрифугой (исчерпан лимит открытых соединений).
    • +2
      У вебсокетов нет таких проблем — пользователь может открывать сколько угодно вкладок. Я так понимаю, что в спецификации вебсокетов нет четко озвученного лимита на количество открытых соединений — и в различных браузерах эти лимиты возможно есть и отличаются — но число все равно очень большое. В случае если браузер не поддерживает вебсокеты — Центрифуга с этим никак не борется — это уже оставлено на участь разработчиков конкретного сайта. В интранете Mail.Ru Group раньше использовался SSE (Server-Sent Events) для подобных вещей — и мы перешли на использование Центрифуги (а вместе с ней и вебсокетов) отчасти потому, что столкнулись с жалобами пользователей, у которых странички подвисали при загрузке.
      • +1
        Спасибо, я именно с SSE и видел подобные проблемы.
    • +1
      это решается, в общем случае, DNS-балансировкой (по моим тестам — достаточно одной строки конфигурации домена и одной строки клиентского кода).
    • 0
      Вообще, стандартное (и самое распространенное) решение этой проблемы – сделать CNAME запись в DNS вида *.comet.example.com, которая будет указывать на comet.example.com. После этого на кленте, при открытие новой вкладки, вы просто рандомно генерите адрес для comet вида blablabla.comet.example.com.
      Но это все прошлый век.
      Самое грамотное решение следующее:
      Браузер может спокойно конектится к тому же домену что и страница, но делать это должна только одна вкладка из всех открытых. Технически делается так – с помощью html5 localStorage табы браузера голосуют между собой и выбирают лидера, который начинает так же через localStorage сообщать всем «жив, работаю и т.д.». Этот лидер уже и общается непосредственно с сервером и мультиплексирует сообщения для других табов (опять же через localStorage).
      Благодаря этому мы снижаем нагрузку на сервер на порядки. В прямом смысле слова – на порядки. В старом варианте, если юзер откроет 10 табов, то все они будут общаться с сервером. В случае с мультиплексированием – только один таб.
      Минус один – мы отрезаем все браузеры, ниже IE8 (все, кто без localStorage). Ну и фиг с ними…
      P.S.: Саму идею этого решения я услышал на конфе несколько лет назад от одного из разработчиков ВКонтакте. Никакой готовой либы в те времена я не нашел и стал стругать собственный костыль. Оказалось все не так уж и страшно. Вышло где-то строк 50.
      Так что… ройте лучше в эту сторону.
  • 0
    Спасибо, я бы даже сказал большое спасибо, пощупаем. А Redis вообще рулит.
  • 0
    А чем вызвана смена лицензии?
    • +1
      я вот в лицензиях совсем не разбираюсь — поэтому заменил BSD на более понятную для себя MIT. Вообще я не очень понимаю, от чего эти лицензии спасают в наше время, захотят использовать открытый код без сохранения копирайта — будут использовать.
      • 0
        BSD и MIT практически одно и тоже.
      • 0
        Ясно. Просто я думал, что вы что-то использовали такое, что конфликтует с BSD лицензией (какая-нибудь либа или фреймворк), поэтому и поинтересовался
  • +1
    Класс! Приятно видеть, что проект развивается!
    Вы не думали подготовить докер контейнер с центрифугой?
    Как думаете, будет ли плюсом, если центрифуга была бы написана не на питоне, а на эрланге?
    • 0
      Спасибо за добрые слова!

      Докер-контейнер было бы неплохо сделать — вот открыл issue, теперь не забуду

      Я с самого начала разработки считал, что Erlang был бы идеальным языком для подобного сервера. Но на выходе у Python есть большой плюс — понятный для большого числа программистов (а самое главное для меня самого) код, что немаловажно для open-source проекта.
      • 0
        Я думаю главной фишкой эрланга была бы независимость от внешнего хранилища при работе в кластере — работа в кластере заложена в отп.

        Кстати, у вас центрифуга работает сингл нодой или кучей через редис?
        • 0
          Да, согласен, архитектура была бы на голову выше. Я часто сетую, что несколько раз брался за Erlang, восхищаясь насколько хорош он для распределенных приложений, но… чуть отойдешь от чистой передачи данных по сети — и вот уже проблемы — с юникодом беда, с библиотеками беда — меня это останавливало, тем более после Python. Может все это не правда, или уже не правда — так как я все-таки далек от Эрланга… Что вы думаете по этому поводу?

          Я возможно не совсем понял вопрос — как в интранете Mail.Ru работает Центрифуга? Если так — то у нас одна нода без Редиса — хватает с головой пока что. Максимально одновременно было около 1.5 тыс. соединений. Немного — но больше из корпоративного портала не выжмешь:) Но если станет не хватать — подключим Redis.
          • 0
            У меня на SockJS + Tornado (но без центрифуги) порядка 2-3к пользователей постоянно в онлайне, ожидается прибавление ещё 6к пользователей на этой неделе.
            Посматриваю в сторону pub/sub, в основном, для отказоустойчивости.
            Можете описать, как у вас устроена работа с pub/sub?
            Я пока думаю о том, чтобы просто сделать общую шину на Redis.
            • 0
              Ну да, в Центрифуге просто общая Redis-шина и есть
              • +1
                Ок, понял.
                Меня беспокоит только то, что тогда на 200к сообщений в секунду узким местом станет Redis, ведь у pypy+tornado+sockjs тот же лимит 200к сообщений в секунду.
                У меня пока сообщений в среднем очень мало, но уж если готовиться к масштабированию, то серьёзно.
                • 0
                  Ну да, к сожалению, это так — так или иначе при таком подходе узким местом является центральный PUB/SUB прокси. Изначально в Центрифуге был ZeroMQ PUB/SUB — можно было запустить несколько нод в brokerless архитектуре — но при этом добавлять новые ноды было очень проблематично — нужно было указывать явно адреса других нод — по-хорошему, надо было бы реализовывать алгоритм поиска и включения новых нод. Плюс проблема с общим состоянием — нужно было бы имплементировать что-то вроде Clustered Hashmap Protocol, например. Так что Redis — это решение достаточно быстрое и простое.
          • +1
            ООО, некоторые вещи после ОО языков (я рубист) в эрланге выносят мозг. Да, есть куча неудобств которые решаются копанием. С юникодом проблем не испытвал. Я в свое время написал бекенд для pusher на эрланге (erlypusher). Сделал основной функционал (публичные и приватные каналы), почти доделал презенс каналы и понял, что надо все переписывать (тяжело строить хорошую архитектуру в функциональном языке без опыта). Потом наткнулся на elixir и понял, что переписывать надо будет именно на нем. Из-за синтаксического сахара эликсир сильно приятнее эрланга.

            Значит вы сделали редис наперед. Я в ерлипушере начал с мультинодовости, но когда делал презенс каналы не разобрался как настроить мнезию на нескольких нодах и сделал однонодовым.

            Кмк, сейчас гораздо важнее иметь удобный докер контейнер, чем мультинодовость
            • 0
              Кстати, докер-контейнер, как оказалось , уже использовался для Центрифуги программистом из ЮАР:) Ох уж этот open-source!
              • 0
                классно!
  • 0
    Можно ещё посмотреть crossbar.iowamp.ws роутер на Python.

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.

Самое читаемое Разработка