Верно ли я продумал архитектуру мессенджера?

Я разрабатываю pet-project мобильное приложение в котором есть возможность обмениваться real-time сообщениями. Сложность мессенеджера, с точки зрения функционала, минимальная, а именно:

1. Есть возможность общаться в личных сообщениях 1-1
2. Есть возможность общаться в групповом чате, которое создает приложение. Сам пользователь создать групповой чат не может
3. Пользователь может написать и прочитать сообщение.
4. Пользователь может видеть, что его сообщение прочитано / не прочитано

Никаких доп.возможностей в стиле прикреплений файлов, фоток, геопозиций нету.

Стек следующий: Go на бэкенде из-за коробочных горутин/каналов. Redis как кэш + pub/sub. PostgreSQL как хранилище.

Схема БД следующая

603ce75b0535f146028827.png

Задачи такие:
1 - Получать список всех чатов пользователя с последним сообщением в этом чате.
2 - В real-time обновлять сообщения в списке при поступлении новых сообщений
3 - При входе в конкретный чат обмениваться сообщениями в real-time
4 - При скроле чата подгружать данные из базы.

Как планирую сделать:

1. На бэкенде сделаю api для получения списка всех чатов. При входе в приложение буду посылать запрос на /api/chats и доставать из постгреса все чаты пользователя с последним сообщением. Результат сохранять в кэше.

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

3. При входе в конкретный чат будут подключаться к еще одному сокету и заходить на канал редиса. При отправке сообщения сохранять его в БД

4. При входе в конкретный чат подгружать из бд последние 20-30 сообщений. При скроле подгружать еще.

Вопросы, которые не могу понять:

1. Нормально ли держать несколько сокетных соединений для разных целей, таких как обновлять список чатов и сообщения в конкретном чате.

2. Верна ли та архитектура, которую я выбрал? Что можно улучшить?

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

4. По какому принципу лучше кешировать чаты? По ID пользователя или по ID чата или как-то еще?

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

6. Может быть вместо кеша в редисе хранить данные в локальном кэше устройства?

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

P.S. в таблице messages так же есть поле is_read, которое я добавил уже позже, после рисования схемы, которое отвечает за "прочитано/не прочитано"
  • Вопрос задан
  • 217 просмотров
Пригласить эксперта
Ответы на вопрос 2
@dmtrrr
Backend developer
> Пользователь может видеть, что его сообщение прочитано / не прочитано

Непонятно как при такой схеме БД реализовать это требование.
Ответ написан
@0nkery
1. Держать несколько соединений не нужно. Результаты прослушки редиса можно возвращать через один сокет.
3. Да, разумеется, но будет ли большое количество пользователей? Если да, то ознакомьтесь с опытом Discord -- https://blog.discord.com/how-discord-stores-billio.... БД придется менять, скорее всего.
4. По айди чата, если планируются разные виды чатов (1-1, групповой).
5. Надо смотреть по доступным ресурсам. Кэш можно ограничить по памяти, чтобы не расползался. В таком случае какие-то чаты могут вывалиться или по каждому будет закэшировано немного, но что поделать.
6. Хранить что-то в устройстве придется, чтобы показывать хотя бы старые сообщения, если нет сети, к примеру.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы