Проектирование highload чата

Привет, читатель!

В этой статье я хотел бы поделиться своим опытом разработки высоконагруженного чата, консультантов, который используется более чем на 300-та сайтах и в день создается около 4000 чатов и 150 000 тысяч сообщений.

Стэк технологий на которых я разрабатывал чат:

1) AngularJS

2) NodeJS

3) MongoDB

4) Socket.io

5) Electron

AngularJS

Angular используется в самом виджете чата, который выводится на сайтах и в интерфейсе консультанта.

NodeJS

На NodeJS написан сокет сервер и админка ко всей кухне.

MongoDB

В качестве базы используется MongoDB, запись и чтение с нее осуществляется быстрее чем в MySQL в 16 раз.

Socket.io

Хорошая реализация сокет клиента-сервера, протокол WebSocket.

Electron

Фреймворк для разработки кроссплатформенных десктопных приложений.

Приступим. На картинке ниже видна архитектура всего приложения.

На этой схеме мы видим, что у нас один инстанс сервера, один инстантс MongoDB базы и клиенты который подключены к серверу по сокетам. Клиенты - это сами операторы и пользователи сайта у которых появились вопросы.

HTTP запросы есть только в админке, это на самом NodeJS сервере и один запрос есть для загрузки фотографий консультантов. Все остальные запросы идут по WebSocket, что дает нам высокую скорость передачи данных от клиента к серверу. Для тех кто в танке, WebSocket - это протокол Real-time сообщений разработанный гуглом.

В чате всего 4 коллекции данных.

1) Коллекция с чатами

2) Коллекция с операторами

3) Коллекция с сообщениями чатов

4) Коллекция с сайтами (сайты на которые добавлялись виджеты чата)

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

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

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

{  "avatar": "1409004359-thumb.jpg", // Прогнозируемая картинка, которая обрезается в данный момент  "original": "1409004359.jpg" // Уже загруженное изображение  }

Таким образом мы сократили время ответа запроса на время, которое требовалось для обрезки изображения с помощью асинхронного выполнения и прогнозирования.

По интерфейсам оператора и администратора, оба интерфейса находятся на сервере, интерфейс оператора загружается в electron приложение с сервера.

Самая сложная часть пожалуй это выбор оператора на которого назначится новый пользователь с чатом. Алгоритм следующий.

Этот алгоритм выполняется за одну миллисекунду, я засекал. Как удалось добиться такой скорости?

Во-первых: Операторы которые сейчас онлайн хранятся в обычном массиве на NodeJS сервере, это возможно благодаря тому, что NodeJS приложение работает как демон и не пересобирается на каждый запрос полностью.

Во-вторых: Хорошая структура данных, в которой хранятся онлайн операторы, советую прочитать книгу о структурах данных

В-третьих: Использование MongoDB

В-четвертых: Использование WebSocket.

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

На самом деле, об этом чате можно говорить еще много и много и о архетектурных решениях и об алгоритмах и так далее. По-этому я закончу на этом.

P.S, каждому советую изучить книги по параллельному программированию и дискретную математику для программистов.

Пожаловаться Подписаться
1 ответ
proweber1

Прощу прощения за ошибки в тексте и в диаграмме алгоритма выборки оператора, я торопился

авторизуйтесь чтобы ответить