О корпоративном мессенджере замолвите слово



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

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

От корпоративного Jabber к Slack
Давным-давно в далекой-далекой галактике, когда в Selectel работало не более 50 сотрудников — каждый использовал для коммуникации разные средства. На тот момент ICQ еще на потеряла актуальность, кто-то зависал в IRC, а кто-то вообще использовал e-mail как основной способ обмена данными. Чтобы привести коммуникации внутри компании к единому стандарту и обеспечить безопасность требовался общий корпоративный мессенджер. По многим причинам, на тот момент, Jabber показался наиболее подходящим:
  • Возможность общения в «комнатах» (аля IRC).
  • Шифрование сообщений с помощью PGP/GPG.
  • Поддержка истории сообщений.
  • Обмен файлами.
  • Крайне низкие требования к серверной инфраструктуре.
  • Возможность инкапсуляции той же ICQ, IRC, etc. внутрь XMPP-протокола.
  • Большое количество приложений-клиентов под любые операционные системы.

Практически нулевая стоимость внедрения была крайне привлекательна, но вместе с преимуществами Jabber имеет и множество серьезных недостатков:
  • Высокий расход батареи на мобильных устройствах.
  • Существенный трафик за счет избыточности (сжатие и шифрование одновременно не поддерживается — приходилось с этим мириться).
  • Некоторые клиенты испытывали проблему с неверно выбранной кодировкой по-умолчанию (UTF-8 only).
  • Обмен файлами требует прямой связности между двумя клиентами.
  • XEP-0045 (Multi-User Chat Extension) — мрак и ужас (кто знает, тот поймет).

Перемен требуют наши сердца
Время шло. Количество сотрудников, отделов, сервисов и оборудования росло. Именно на этом этапе потребовались новые функции, который просто невозможно было обеспечить при помощи Jabber. В первую очередь — это возможность интеграции с системами мониторинга и управления инцидентами. Разумеется, можно было писать под каждую задачу свой собственный код, где-то его разворачивать, формировать из него Jabber-понятный XML и отправлять получателям, но такой подход сразу тащил за собой массу проблем.

Инструменты меняются, системы тестируются и проходят тщательный отбор. Писать код интеграции Jabber под каждый инструмент — по сути каждый раз изобретение своего собственного велосипеда, который будет ломаться каждый раз, как только происходят изменения в работе инструмента. В конце концов это стало одним из критериев выбора другой платформы, которой стал всеми любимый и ненавидимый Slack.

Чего мы хотели добиться? Любое событие от мониторинга или непосредственно от устройств должно «прилетать» прямо в мессенджер ответственному сотруднику или отделу. Обо всех инцидентах инфраструктуры должны быть мгновенно оповещены все сотрудники, чтобы действовать соответствующим образом.

Также крайне удобной функцией являлась интеграция с Google Docs. При совместной работе с документами Slack оповещает о сделанных изменениях и тем самым сразу обращает на них внимание. Впоследствии туда добавились и разнообразные боты, например, наш собственный HR-бот, позволяющий бронировать переговорные комнаты, узнавать даты выплаты заработной платы и даже просто поболтать с «искусственным интеллектом» (для особых интровертов).

Именно так Slack стал для нас информационным центром, позволяющий каждому сотруднику в срок получать нужную ему информацию и быть в курсе происходящих в компании событий.

От Slack к поиску альтернативы
Selectel продолжал активно расти и вот количество сотрудников перевалило за 350 человек. Все использовали Slack, однако, цена такого взаимодействия даже на самом недорогом тарифе с корпоративными функциями достигла немалой суммы в размере $38 000 за год. Наш рост не прекращался, а следовательно, встал вопрос — как можно сократить эти расходы? Так мы стали подыскивать альтернативу.

Бесплатные
Прежде всего наше внимание привлекла к себе платформа Zulip, являвшаяся основным средством корпоративной коммуникации в Dropbox. К слову сказать, именно Dropbox и выкупил Zulip в 2014 году, после чего опубликовал исходный код приложения на Github. Таким образом платформа стала доступна каждому под свободной лицензией Apache 2.0.

Еще один плюс — наличие клиентов под все популярные мобильные и десктопные платформы, за исключением почившего Windows Phone. Также Zulip, написанный на Python и использующий PostgreSQL в качестве базы данных, легко интегрируется практически со всеми популярными системами и поддерживает множество разных сервисов. Но без ложки дегтя не обошлось. В процессе тестирования наши разработчики отметили низкую скорость работы в определенных условиях. Также стоит отметить необъяснимую сложность структуры: потоки делятся на темы, темы содержат в себе чаты.

Вторым претендентом на приз стать нашим корпоративным мессенджером стал Rocket.Chat, выпущенный по лицензии MIT. Написанный на Java Script в связке с MongoDB мессенджер уже завоевал свою популярность среди профессионалов. По функциональным возможностям Rocket.Chat также очень схож со Slack: также позволяет создавать публичные каналы, закрытые группы и обсуждения, обмениваться файлами. Поддержка аудио- и видеосообщений есть, но эти функции работают не очень стабильно, поэтому у нас не используются. Работа над улучшением Rocket.Chat ведется постоянно, о чем свидетельствует множество коммитов на Github.

В процессе тестирования были выявлены некоторые недостатки, такие как:
  • невозможность открывать внутренние ссылки внутри клиента;
  • отсутствие некоторых методов в REST API, например, обновления интеграции (добавить или удалить можно, а обновить нельзя);
  • нестабильность работы Windows-клиента.

Помимо вышеперечисленных двух платформ мы также рассматривали кроссплатформенный мессенджер Riot.im. В нем используется протокол Matrix, разработанный в 2014 году как альтернатива существующим XMPP и IRC. Плюсом протокола является возможность использования «мостов» в такие популярные мессенджеры, как:
  • Telegram;
  • WhatsApp;
  • Discord;
  • ...
Однако, работа над серверной частью Synapse и клиентом Riot.im ведется не слишком активно (гораздо медленнее, чем над Rocket.Chat), что автоматически означает отсутствие оперативного устранения багов и необходимость доставать напильник.

Платные
Кроме бесплатных вариантов мы рассматривали и платные. В частности мы обратили внимание на одного из основных конкурентов Slack — Mattermost. Несмотря на наличие версии The Open Source Mattermost Team Edition — все нужные нам корпоративные функции доступны только в платных версиях.

Несмотря на заявления создателей Mattemost о том, что использование их мессенджера дешевле Slack — мы посчитали и пришли к выводу, что использование Mattermost обойдется нам дороже. Разумеется, такой вариант для нас не являлся приемлемым.

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

Подведение итогов
Посчитав все плюсы и минусы разных платформ, мы пришли к следующему выводу: «переезжать» на Rocket.Chat. В случае выявления серьезных проблем в работе запасным вариантом был выбран Zulip. После того как решение было одобрено руководством, началась подготовка инфраструктуры для развертывания.

Как осуществлялся переезд
Мы уже упоминали, что Rocket.Chat представляет собой серверное приложение, написанное на JavaScript и использующее MongoDB в качестве хранилища сообщений. Поэтому в первую очередь нам следовало обеспечить отказоустойчивость базы данных. MongoDB «из коробки» поддерживает аварийное переключение (Failover) при помощи механизма репликации, поэтому мы развернули 3 небольшие виртуальные машины в разных регионах (Москва и Санкт-Петербург) и настроили механизм Replica Set. Само по себе приложение архитектурно построено таким образом, что мы передаем ему данные обо всех репликах в наборе и оно само распределяет нагрузку между ними (с какой реплики читать и в какую писать).

Переходим к серверному приложению. Мы используем официальный Docker-образ Rocket.Chat, размещенный в DockerHub. Приложение развернуто в 3-х экземплярах на разных физических хостах и управляется с помощью Kubernetes. Нагрузка на поды (от англ. «pod» — стручок, капсула) балансируется также средствами Kubernetes, обеспечивая тем самым не только равномерность утилизации ресурсов, но и возможность производить обновления без остановки сервиса. В этом случае один из подов останавливается, корректно обрабатывая все активные подключения, и вместо него запускается новый под с обновленной версией образа приложения. Помимо легкости обновления, такой подход позволяет буквально в 1 клик масштабироваться горизонтально при возрастающей нагрузке.

Следует отметить, что Rocket.Chat имеет важную особенность. Все пересылаемые файлы экземпляр приложения по умолчанию хранит локально, а не в БД. Поэтому, когда требуется работа нескольких экземпляров приложения — нам потребовалось реализовать общее хранилище. Для этого мы воспользовались нашим S3-совместимым Облачным хранилищем, доступ к которому организовали для всех экземпляров приложения. Это позволило всем экземплярам приложения хранить файлы в едином месте, но это не стало потенциальной точкой отказа, ведь как мы уже упоминали в наших статьях — все данные, размещенные в облачном хранилище, реплицируются N+2.

Таким образом мы получили надежную отказоустойчивую инфраструктуру для работы Rocket.Chat, заложив в нее возможность горизонтального масштабирования. Когда нагрузка вырастет — мы будем к этому готовы.

Экспорт и импорт данных
Мы чаще всего рассказываем о том, как успешно решаем достаточно нетривиальные задачи, однако, при переезде нам так пока и не удалось корректно перенести историю сообщений из Slack в Rocket.Chat. Точная причина пока неизвестна, но предполагаем, что на момент переноса был баг, из-за которого файл экспорта был сформирован некорректно. Для нас это не было критичным, поскольку все сотрудники заранее были оповещены о «переезде» и самостоятельно сохранили важные для них данные. Так что, если планируете переезд — учитывайте, что на этапе импорта данных может возникнуть подобный «сюрприз».

Еще одним нюансом будут push-уведомления в мобильных приложениях. Дело в том, что сам Rocket.Chat по умолчанию использует свой собственный платный push-gateway. А это значит только одно — нужно либо консолидировать все push-уведомления на отдельном сервере, либо настраивать подключение сервера Rocket.Chat напрямую к серверам Google и Apple. В любом случае требуется самостоятельная подготовка мобильного приложения, путем добавления внутрь сертификатов и настроек.

Не менее важная часть переноса интеграций прошла на удивление проще. Оказалось, что достаточно всего лишь поменять Incoming Webhooks со Slack на Rocket.Chat и большая часть интеграций заработала корректно. Можем с уверенностью сказать о практически полной совместимости. Это сэкономило нам массу времени.

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

Заключение
Мы пока что используем Rocket.Chat недостаточно долго, чтобы однозначно сделать какие-то определенные выводы. Но первые же недели использования показали, что к новой платформе пользователи быстро привыкли и не испытывают серьезных проблем или трудностей. Через какое-то время мы еще раз вернемся к этой теме и расскажем о том — удалось ли нам решить проблему с импортом данных. Оставайтесь на связи!