Это текст доклада и видеозапись моего выступления с конференции.
rumeetup.ru представлены в удобном для чтения формате.
Я также удалил часть вступления, чтобы не тратить время читателей на лирические отступления о причинах, побудивших меня приступить к разработке моего Серверы Comet с открытым исходным кодом с нуля на C++.
Видео выступления Введение, не содержащее технически важных подробностей
Слайд 1 – Приветствие
Слайд 2 – немного о проекте
5 лет назад я посетил конференцию highload++ 2012, где мне пришла идея создать сервер Comet. Никаких объективных причин для этого у меня не было.Мне просто понравилась эта идея.
Более того, у меня был опыт прошлых проектов, который я мог применить.
С тех пор я потратил на этот проект почти 2000 часов.
Для чего я написал SaaS-сервис Comet и его аналог с открытым исходным кодом таким образом, чтобы их API были совместимы, что позволяет переключаться между SaaS-версией и версией с открытым исходным кодом без изменения кода.
За это время мне удалось написать подробную документацию на русском и английском языках.
Несмотря на то, что я использую CppComet в продакшене уже почти 4 года, я до сих пор активно его развиваю, постепенно добавляя новые функции.
Например, на прошлой неделе я добавил функцию кластеризации.
На протяжении 4 лет я занимался технической поддержкой пользователей проекта.
И по каждому вопросу я улучшал API и документацию, чтобы следующим пользователям было проще.
Слайд 3 – Аналоги
Мой проект не делает ничего революционного, что невозможно реализовать с помощью других инструментов.Поэтому на этом слайде я составил список конкурирующих проектов.
Библиотеки
SaaSСлайд 4 – Введение
Наверное, перед каждым разработчиком рано или поздно встает задача создать свой чат или реализовать какие-то уведомления в реальном времени.И хорошо, если проект новый и можно на этапе проектирования учесть, где и какие данные должны обновляться в реальном времени.
Но это не всегда происходит. Иногда вам необходимо добавить обновление данных в реальном времени в существующий проект. Предположим, мы хотели, чтобы комментарии к статьям на сайте обновлялись у пользователей сразу, а не после перезагрузки страницы.
Первое и самое простое решение — запрашивать данные о новых комментариях с сервера ajax-запросом раз в секунду.
Решение простое и вполне рабочее, некоторые именно так и делают. Например, в админке, где сидит максимум 1 – 2 человека.
Слайд 5
Но когда посетителей более одного, этот код идеален, если вы хотите провести ддос-дос вашего сайта даже при относительно небольшом трафике.
Слайд 6
Вместо того, чтобы отправлять множество запросов от клиента на сервер, рациональнее отправлять новые данные клиенту в момент их появления на сервере.В этой схеме клиенты JavaScript подключаются к серверу Comet через веб-сокеты и ждут уведомлений от бэкэнда.
И веб-сервер отправляет уведомления о событиях на сервер Comet в надежде, что эти уведомления будут доставлены во фронтенд. По своему опыту скажу, что удобно отправлять данные на сервер кометы сразу после того, как эти данные были записаны в базу данных сайта.
Слайд 7
Сервер Comet имеет два интерфейса API, один для подключения через веб-сокеты из браузеров.И второй интерфейс для отправки запросов с бэкенда.
Для API JavaScript не существует определенного выбора протоколов.
Мы работаем с использованием вебсокетов.
А вот API для вызовов из бэкенда можно реализовать по-разному.
Слайд 8 – API
Сначала я, не долго думая, написал простой API для своего протокола и PHP-клиент для него.Но получившийся мотоцикл было легко разработать и сложно обслуживать.
В результате обеспечение обратной совместимости всех версий API на нескольких платформах оказалось трудоемкой задачей.
По сравнению с его протоколом работа с известным REST API выглядит очень привлекательно.
Но на практике при работе по протоколу http для каждого запроса необходимо установить сетевое соединение, выполнить запрос и закрыть сетевое соединение.
Это дольше, чем вариант работы через tcp, где все запросы обрабатываются в рамках одного сетевого подключения.
И в итоге я решил пойти по пути, который был реализован в SphinxSearch, реализовал серверную часть протокола mysql и появилась возможность работать с сервером Comet с помощью клиентов MySQL, которые доступны для каждого более-менее популярного языка.
Слайд 9. API CometQL
Сервер Comet стал делать вид, что это MySQL-сервер.И API стал похож на доступ к базе данных.
вставьте для отправки данных клиенту, выберите для получения информации от кометы сервера.
Имя таблицы указывает на объект, над которым выполняется операция.
Имя базы данных символизирует версию API, над которым мы работаем.
Пока версия 1. Так как обратная совместимость не ломалась уже более 2 лет.
Слайд 10. API JavaScript
API JavaScript скрывает много кода для обработки ошибок, функций кластеризации и различных оптимизаций.Например, сколько бы вкладок одного сайта мы ни открыли, с сервером Comet будет установлено только одно сетевое соединение, а остальные вкладки будут общаться с сервером Comet через общее для всех соединение.
Слайд 11 – Каналы доставки сообщений
Чтобы получать информацию о любом событии в JavaScript, вам необходимо подписаться на это событие.Например, если мы хотим получать новые комментарии на странице, которая у нас в данный момент открыта в браузере, то мы подпишемся на канал, по которому сервер будет нас о чем-то уведомлять.
После того, как мы подписались, мы можем отправлять данные с сервера в канал, на который мы подписались.
Имя канала может быть любым, главное, чтобы сервер отправлял сообщения в тот канал, на который мы подписались из JS.
Слайд 12 – Получение личных сообщений
В предыдущем примере сообщение мог получить любой, кто знал, на какой канал подписаться.Но это не всегда удобно.
Например, если мы пишем чат и хотим доставить сообщение кому-то конкретному, чтобы другие пользователи не смогли получить это сообщение, то вместо каналов удобнее использовать механизм личных сообщений.
Для этого подпишемся на специальный канал под названием «msg».
Он будет получать только сообщения, адресованные лично нам.
Эта возможность доступна после авторизации пользователя на сервере Comet.
Слайд 13 – Производительность
Измерения производительности и потребление памяти я трачу с помощью tsung, в среднем потребление памяти меньше 5 ГБ ОЗУ для 64000 пользователей .И при этом за счет того, что сервер Comet работает в многопоточном режиме, ему удается практически равномерно использовать все доступные ядра.
Тест, конечно, синтетический; реальная нагрузка в моей производственной среде намного меньше.
На данный момент онлайн до 1500 человек.
В результате серверы загружены лишь на несколько процентов своей мощности.
Слайд 14
В результате мы вернулись практически к тому же объему кода, что я предоставил на первом слайде, но сделали все правильно.И теперь они способны выдержать нагрузку примерно в 5 ГБ ОЗУ на 64 000 онлайн.
Плюс есть возможности кластеризации, масштабирования и отказоустойчивости.
Слайд 15 – Масштабирование
Всегда хорошо планировать заранее возможности масштабирования архитектуры .Я предоставил на кометном сервере возможность кластеризации при котором каждый сервер кластера может получать запросы и пересылать их тем серверам кластера, которые необходимо уведомить о событии.
Операции по вставке данных (вставка и установка) выполняются асинхронно, а это значит, что вам не придется ждать, пока запрос будет отправлен всем серверам кластера.
Операции извлечения данных (выбор и показ) выполняются синхронно.
Слайд 16 – Отказоустойчивость
Если что-то сломается и сервер Comet станет недоступен, то в лучшем случае сообщения перестанут приходить пользователям.Если у нас нет кластера, то очевидно, что все сразу может сломаться, если возникнут проблемы с сервером.
Если есть кластер серверов Comet, то выход из строя одного узла также может быть болезненным, если именно через этот узел мы пытаемся отправить запрос.
Слайд 17
В реальном мире иногда случаются ошибки.И писать такой код для обработки ошибок — не самая приятная задача.
И самое главное, если какой-то из серверов будет недоступен, то с первой попытки мы не подключимся.
Таким образом, вы можете включить haproxy в схему кластера, чтобы сбалансировать запросы между действующими узлами кластера.
Слайд 18
В haproxy есть механизм опроса серверов MySQL и исключения из списка тех, которые не работают. Также есть возможность задать пропорцию распределения нагрузки между узлами кластера.API javascript также имеет встроенную возможность подключения к другому узлу в кластере, если один из узлов недоступен.
В результате, если отключить узлы кластера серверов Comet, функциональность сохранится до тех пор, пока в эксплуатации находится хотя бы один рабочий узел.
Более того, клиентам из веб-браузеров даже не потребуется обновлять страницу.
Все будет скрыто внутри API JavaScript.
Слайд 19 – Планы развития проекта
Слайд 19 – Планы
Первое — улучшения работы в кластере.Поскольку механизм кластеризации я реализовал только этой осенью, мне необходимо накопить пользовательский опыт работы с ним.
И второе — добавление функциональности видеочаты и видеоконференции .
Уже есть демо-версия того, как работает видеочат. Но API еще не полностью создан.
А хотя видеочатами уже можно пользоваться.
Не факт, что в следующих релизах будет полная обратная совместимость для видеочатов.
Я также публикую запланированный функционал на github
Слайд 20 – Несколько примеров, где он уже используется
Слайд 20 – Где это уже используется?
На самом деле мой сервер Comet используется на нескольких десятках сайтов.Вот лишь некоторые из проектов, о которых я знаю.
Первые три имеют встроенный простой чат, общий для всех участников.
Во второй строке есть чат для социальной сети и чат для сайта знакомств.
Слайд 21 – Спасибо за внимание
Слайд 21 – Спасибо за внимание
Теги: #CppComet #CometQL #с открытым исходным кодом #проекты с открытым исходным кодом #websocket #websockets #сервер websocket #api #разработка веб-сайтов #мессенджеры #с открытым исходным кодом #JavaScript #api
-
Поддержание Связи Где Угодно
19 Oct, 24 -
Укрощение Слона Или Что Такое Хюэ
19 Oct, 24 -
Школа 42 Как Павший Воин В Эпоху Covid
19 Oct, 24 -
Набор Сниппетов Для Работы С Jquery.
19 Oct, 24