Делаем веб сервис: виджет для встраивания на сайты клиентов. Будет функция онлайн чат. Как у jivosite.ru
Стоит вопрос, на чем писать сервер обмена сообщениями. Сейчас имеем два вариант:
Node.js.
Плюсы: популярный язык, можно относительно быстро найти разработчика, не дорого.
Минус: пока не ясно как грамотно сделать балансировку нагрузки между множеством серверов. Чтоб собеседники могли подключаться к разным серверам, при этом общаться без проблем, подключать новых собеседников в диалог.
Erlang
Плюсы: судя по описанию языка, наиболее подходит для масштабирования подобных систем. То что его используют Яндекс и FB тоже о чем-то говорит.
Минусы: никто в команде не имел дела с подобным языком. Решение предлагает сторонний разработчик, непроверенный. Велика вероятность, если он сольется, остаться с непонятным кодом, который некому доделать. По биржам фриланса пробежался, Erlang разработчиков крайне мало.
Вопросы:
1. Прошу помочь, на чем лучше остановиться?
2. Возможно есть пути решения на node.js?
3. Или с Erlang не все так страшно?
4. Возможно есть другие подходящие технологии?
5. Возможно вы знаете того кто может помочь за оплату или взяться за выполнение проекта?
P.S.: Не знаю позволяют ли здесь правила искать подрядчиков. Если что, прошу администрацию извинить и затереть пункт 5.
пока не ясно как грамотно сделать балансировку нагрузки между множеством серверов
У вас сколько коннектов-то? До 100к примерно можно смело говнокодить на чем угодно из списка. До 300к можно говнокодить на Эрланге. Все это спокойно будет работать на одной машине.
Вот старая уже публикация про 1м на машине с 128Гб/40 cores на Phoenix: phoenixframework.org/blog/the-road-to-2-million-we...
Это с учетом оверхеда на Phoenix еще. Уберите его, пишите на чистом Эликсире, и будет еще полегче.
На первое время, решение для версии "до 100к" подойдет. Если я верно понял о чем речь. Т.е. 100 000 посетителей онлайн, верно? Теоретически, это +/- 10 000 активных чатов одновременно.
Получается, можно закодить односерверное решение на Node.js. Взять например сервер m4.large 8Гб/2 cores https://aws.amazon.com/ru/ec2/instance-types/ И при повышении нагрузки постепенно переезжать до m4.16xlarge 256Гб/64 cores. И теоретически, до 100к коннектов все будет гладко?
alexperec: 100к коннектов — это 100к открытых страниц с чатами. Это дело можно прямо в процессе разработки тестировать через Tsung.
Вот только вы скорее всего упретесь в память, не доходя до 100к, на NodeJS, потому что нода течет, и утечки обычно где-то в глубинах машины. Так что рассчитывайте, что нода потребует больше памяти на 100к.
В любом случае мы сейчас занимаемся теоретизацией. Практика выглядит так: выбираете любой язык подкидыванием монетки или как угодно, пишете ТЗ и предполагаемый профиль нагрузки (например n клиентов, которые каждые m секунд шлют сообщение k байт стольким-то другим клиентам), делаете из этого нагрузочный тест. А потом идет TDD: даете программисту нагрузочный тест и просите уложиться в нужный latency. У готового решения замеряете память и решаете, достаточно ли это оптимально для вас.
При прочих равных решение на Erlang/Elixir будет оптимальнее, чем на ноде. Но разработчика найти сложнее.
Если вам очень-очень хочется выбрать максимально оптимальный язык, то пишете минимальный прототип на нескольких языках и тестируете его вышеописанным образом. Дорого, долго, но безотказно.
Велика вероятность, если он сольется, остаться с непонятным кодом, который некому доделать. По биржам фриланса пробежался, Erlang разработчиков крайне мало.
тогда о чем вообще вопрос ?
вы уверены что вам нужно будет так сильно масштабироваться как fb ? к слову вк чаты раньше жили на node.js, сейчас на go
Node.js в вашем случае (и по "быстро найти разработчика" и по технической части).
FB, Яндекс, vk не показатель. Другие ресурсы и масштабы. Как правило фреймворки/инструменты от таких мастодонтов пишутся ими для своих же нужд и под эти же нужды затачиваются.
PS:
Быстро найти и не дорого === некачественная работа.
Node.js обманчив своей простотой.
Что касается масштабирования то вы бы могли продумать архитектуру в не зависимости от инструмента таким образом чтоб иметь возможность сайты отдельных клиентов выносить на отдельные сервера. Тем самым распределяя нагрузку по разным серверам.
Если будут вопросы по CppComet пишите, смогу подсказать как его эффективнее использовать.
> продумать архитектуру в не зависимости от инструмента таким образом чтоб иметь возможность сайты отдельных клиентов выносить на отдельные сервера.
что делать когда один сервер не справляется с нагрузкой от одного сайта ?
По вашему CppComet -- интересная задумка использовать MySQL протокол. Как масштабируется ваше решение ?
Надо тоже запилить такое на Ерленге.
Скажите, клиеты уже есть ?:)
что делать когда один сервер не справляется с нагрузкой от одного сайта ?
Тогда конечно браться за кластеризацию. Но в любом случаи это произойдёт сильно позже.
Скажите, клиенты уже есть
- да проект не вчера родился и есть люди которые его используют. Но насколько мне известно среди них пока нет тех кто имел бы по настоящему большое количество пользователей онлайн. Так что пока приходится довольствоваться нагрузочными тестами, а не реальным опытом применения в hightload
интересная задумка использовать MySQL протокол
помимо меня это реализовано в sphinxsearch и это даёт большие возможности по использованию ПО написанного для mysql
На пример можно балансировать запросы через haproxy, а так же использовать mysql клиенты во многих языках не занимаясь написанием клиентского апи под каждую платформу.
Как масштабируется ваше решение?
Есть вариант для отказоустойчивости. Когда 2 или более комет сервера работают совместно. Тогда при отключении одного из серверов ни кто не заметит сбоя. Такой подход используется на сайте https://seregatv.ru/ могу подробно расписать как оно настроено и работает. Но по объёму это больше тянет на отдельную статью. Так что если интересны подробности то могу со временем написать отдельную статью.
Вариант же для разделения нагрузки между серверами есть, но имеет несколько ограничений. Суть его заключается в том что из JavaScript API подключение осуществляется к одному серверу из списка.
А из бекенда надо отправить сообщение на каждый сервер из кластера по отдельности. И тогда сообщение точно дойдёт до всех пользователей. Такой метод работает так как сообщений обычно в разы меньше чем подписчиков из Js, но он реально не очень удобен. В данный момент я работаю над реализацией полностью прозрачной для клиентов кластеризации. Но пока эта работа не завершена.
> помимо меня это реализовано в sphinxsearch и это даёт большие возможности по использованию ПО написанного для mysql
На пример можно балансировать запросы через haproxy, а так же использовать mysql клиенты во многих языках не занимаясь написанием клиентского апи под каждую платформу.
Я знаю об эмуляции протокола для MySQL в отдельных случаях, когда это допустимо бизнес задачей.
В вашем случае не представляю как сделать подписку на события внутри MySQL-протокола, скорее всего её там нет, следовательно сервер не может уведомить серверную-часть в реальном времени о поступившем событии.
> А из бекенда надо отправить сообщение на каждый сервер из кластера по отдельности.
Костыльненько :) В таком случае проще написать утилитку на стороне сервера, которая будет делать это, чтобы скрыть сам факт такого костыля. + В данном случае, опять же, ваша масштабируемость ограничена самым медленным сервером, который способен обработать весь поток сообщений.
Я советовал бы Вам посмотреть в сторону Erlang. Все проблемы которые вы решаете там уже решены.
Ну разве что Erlang - интерпертируемый код виртуальной машины, а не компилируемый, т.о. теряется некоторая производительность, но при этом скорость разработки существенно выше.
А из бекенда надо отправить сообщение на каждый сервер из кластера по отдельности. Костыльненько :)
В целом я так и планирую. Только сделать это уже по уму внутри сервера, тогда будет возможность для каждого типа запросов предпринять специфичные оптимизации. А так же не отправлять запросы на все сервера кластера если сообщение адресовано персонально конкретному пользователю.
В вашем случае не представляю как сделать подписку на события внутри MySQL-протокола, скорее всего её там нет, следовательно сервер не может уведомить серверную-часть в реальном времени о поступившем событии.
Да действительно такой фишки нет. Сейчас решается тем что сообщения идут через аякс на сервер бекенда а от туда идут на комет сервер для доставки сообщений. Эта схема для многих php разработчиков является понятной, привычной и удобной. Так как обычно перед рассылкой сообщений требуется провести его валидацию и прочие операции то как правило в комет сервер уходит совсем не то что отправлено аяксом в бэкенд.
не представляю как сделать подписку на события внутри MySQL-протокола
Я пока не пробовал но хотел занятся таким. Мне кажется это должно выглядеть как select запрос из одного или нескольких каналов который не отдаст ответ до тех пор пока не придёт порция данных хотя бы из одного канала. Так что не вижу особой проблемы в реализации.
Для публики: Я - это тот самый разработчик, который предлагает Erlang.
Давайте теперь по пунктам:
1. Erlang :)
2. Я не специалист в node.js, не скажу. Я уже писал вам в письмах почему Erlang.
3. Абсолютно не страшно. "Erlang учится за 2 недели, то есть за год можно выучить до 26 Эрленгов" ( tonsky.livejournal.com/281876.html )
4. Наверное есть.
5. Я бы усомнился в вашей адекватности. Предоставив какую-то мокап админку, вы просите оценить стоимость и объем работ по серверу-чата. При этом абсолютно уверуя, что мне достаточно информации.
Также вы всегда можете найти ерланг разработчика в русской расылке Erlang: