#c# #.net #sql-server #database
#c# #.net #sql-сервер #База данных
Вопрос:
Мне всегда было интересно, как огромные приложения (такие как Facebook) обрабатывают уведомление пользователей о событиях (например, кто-то отправил вам сообщение) практически в режиме реального времени без объединения базы данных каждую секунду / минуту и т.д. (я предполагаю, Facebook не проверяет, есть ли какие-либо новые сообщения для вошедшего в систему пользователя каждую секунду). Есть ли какой-либо способ в Sql Server получать уведомления в приложении C # при изменении базы данных (строка вставлена или обновлена)?
Чтобы (надеюсь) сделать вещи немного более практичными:
Как бы вы справились с настольным приложением чата, которое подключено к серверу базы данных и позволяет пользователям отправлять сообщения друг другу, предоставляя мгновенные уведомления для человека, получающего сообщение?
Как бы вы обработали уведомление пользователя о сообщениях, которые они получили, находясь «в автономном режиме»?
Давайте предположим, что приложение будет обрабатывать несколько сотен / тысяч пользователей, и уведомления должны быть (относительно) мгновенными (без объединения базы данных каждые 10 секунд, чтобы увидеть, есть ли какие-либо новые сообщения).
Ответ №1:
Использование базы данных в качестве центра узла связи является узким местом и, скорее всего, не будет хорошо масштабироваться. Поскольку вы упомянули .NET, вам следует проверить SignalR. https://www.asp.net/signalr
В простом варианте использования вы могли бы выполнять запись в базу данных и одновременно отправлять события уведомления, чтобы сообщить клиентам проверить наличие нового материала, который вы только что записали в базу данных.
Ответ №2:
Это зависит от того, насколько точным вам нужно быть. Facebook не обязательно должен быть точным, поэтому может позволить себе делать это в любом случае, когда захочет. Для точной реализации, например, когда возникает проблема с качеством обслуживания, так что сообщение должно попасть по назначению за определенное время, вам необходимо иметь двунаправленную связь между клиентом и сервером. Websockets делает это на HTTP, хотя на самом деле это просто маскирует облегченный механизм опроса HTTP.
С точки зрения обеспечения того, чтобы конкретный сеанс (пользователь) получал сообщения, у меня возникло бы желание использовать базу данных в памяти (например, Redis) в качестве кэша для записи для всех генерируемых сообщений. То, как вы обновляете хранилище сеансов в Redis для сеанса ваших пользователей, зависит от способа создания сообщения; это может быть
1) Из-за обновления базы данных 2) Из-за ввода внешней системы 3) Из-за того, что прошло некоторое время и достигнут некоторый привратник расписания.
Во всех этих случаях вы можете использовать другую технологию для уведомления распределенного кэша сообщений, поэтому в SQL Server вы можете сгенерировать триггер для записи в таблицу исходящих сообщений, возможно, используя SQL Server Object Broker или MSMQ в качестве дампа сообщений. Отдельный процесс проанализирует дамп сообщения и загрузит кэш Redis.
Ответ №3:
Как упоминалось выше, ответственность за это должен нести сервер (приложение), а не БД
Я бы сделал это следующим образом:
Приложение (пусть это будет центральный сервер) должно убедиться, доставлено сообщение или нет. Если сообщение доставлено, сохраните его в истории (db). Если это не так, сохраните это в отложенных сообщениях (db).
Если пользователь находится в автономном режиме, наступит момент, когда он / она войдет на сервер. После завершения входа в систему сервер отправляет ему отложенные сообщения.
В случае бессерверной / распределенной системы логика будет такой же, за исключением того, что отложенные сообщения могут сохраняться либо только на стороне клиента, либо на некоторых узлах, которые выполняют маршрутизацию сообщений