Ребят, добрый все вечер! Сложилась следующая ситуация, я пришел в проект на котором происходит следующее.
В определенное время суток, люди выставляют товары, а потом в общей таблице, где видны все поставщики они меняют цены на своих товарах . Суть в том, что каждый их них хочет попасть на первые строчки, а это возможно, только уменьшая цену. На данный момент, прошлый программист сделал так, что с клиента посылает запрос на сервер каждые 4 секунды, генерирует на сервере вьюху и отдает клиенту, а аякс ее отрисовует. Но такой подход создает колоссальную нагрузку, особенно если учесть, что на страницу выгружаються сразу все записи из базы. А их количество варируеться в очень большом диапазоне, от 50 и до 500 записей, прям лекго. Все это дело выбираеться одним запросом ии так каждые 4 секунды. В конечном итоге сервер просто ложиться, даже когда сидит 2 человека начинаються проблемы.
По факту один клиент делает 15 запросов в минуту, в среднем, клиентов около 15. Но дальше их будет только больше. Но даже, когда их 15, мы получаем 225 запросов в минуту.
Если я правильно понимаю, все это дело лучше сделать на сервере и отдавать сразу всем клиентам. И тогда у меня получиться всего 15 запросов в минуту. Результат одного запроса будет отрисован сразу 15 пользователям.
Но есть проблема, если использовать pusher то там лимит на размер сообщения 10кб, у Ably лимит 64кб, но можно сделать 256кб на enterprise плане за овер дорого. Но проблема в том, что этого не достаточно, на данный момент, чтобы ответ от сервера, который отрисовуеться с помощью аякса, весит 1.2Мб.
Подскажите как правильно поступить с решением такой ситуации, как вообще правильно обновлять информацию в риалтайме, но чтобы это было быстро.
sim3x, смотрите, каждый поставщик имеет общий список товаров. Что-то вроде шаблона, все что он может изменять - это кол-во и цену. Всего 2 значения. А на другой странице, выводиться значения из базы. Это 1 запрос из которого составляеться одна большая таблица, в которой отображаеться имя поставщика, а в нем вложены товары.
Более того, 2 разных поставщика могут добавить 300 одинаковых товаров, но указать разное кол-во и цену. А еще 3 других поставщика могут добавить 900 товаров. И все эти данные будут выгружены одним запросом, по скольку нужно отобразить сразу всю таблицу. Плюс на странице с этой таблицей, в цикле из браузера посылаеться асинхронный запрос, на который сервер отвечает всеми записями, которые добавлены в базу и отдает их в виде html (только таблица). Ну и аякс, получая ответ рендерит все это дело.
А пользователей в среднем 15 и каждый добавляет по 100 - 1000 товаров. Ну и соответственно, каждый пользователь делает запрос в базу на выборку. Если посчитать то получаеться 1 очень большой запрос. И самое плохое, нельзя использовать пагинацию и разбивать запрос на части, ровно как и нельзя при скроле страницы подгружать значения(опять таки, разбивая запрос на части). Нужна сразу вся таблица с информацией о всех пользователях и добавленныъх ими товаров.
sim3x, вы правы, но на деле, почти все пользователи в основном добавляют технику эппл и как правило они заполняют примерно одно и тоже. Например, одних только iphone 8, будет около 200 позиций, ибо они разделяються на цвет, память и страну. А в списке есть все айфоны от 5 до xs.
Ленивое решение
Сохраняем выборку в жсон файл и отдаем его
После апдейта обновляем файл
В файле только ид "товара" и его текущая цена
Всю остальную инфу по товару отдаем из своего апи. Можно в том же духе - просто жсон файл
Берете socketcluster (если self-hosted) либо любое другое решение (если не self-hosted), поднимаете. Далее выкидываете все, что написал предыдущий прогер. Припиливаете вью, делаете вью компайл на стороне клиента. При заходе на страницу - подписываетесь на канал сокета (напрямую, либо с помощью либы-обложки Echo от laravel), потом загружаете ваши 50-500 записей, а после слушаете в этом канале эвенты ИЗМЕНЕНИЙ каждой отдельной записи. Они же не все 500 одновременно изменяются? Ну и при изменениях отправляете эти эвенты с помощью встроенных средств laravel.
Это самая обычная схема работы сокетов. И тут вам не то что 10кб, а несколько десятков байт должно хватить на каждое сообщение. Конечно, их будет много, но сокеты на это и рассчитаны. Если не хотите платить (но прийдется платить за сервак и админить) - берете self hosted.
Спасибо за содержательный ответ. Изначально я хотел обойтись малой кровью и отправлять всю страницу через веб сокет. Но сейчас понимаю, сколь глупым решением это было. Значит буду перестраивать таблицу и пользователей в ней на клиенте. Ну и ко всему прочему, я думаю, что лимитов Pusher, который я уже использую для начала, будет за глаза, даже на бесплатном тарифе. Ну а по мере необходимости уже решу, что будет удобнее.
Чем больше знаю, тем лучше понимаю, как мало знаю.
Гы-гы-гы, 1.2 Mb 225 раз в минуту?
Отправляйте только записи, изменившиеся после предыдущего запроса.
Убирайте лишние подробности из ответа.
Сделайте свой компактный формат ответа вместо (скорее всего) JSON.
Правильный, не правильный... А какие ещё варианты-то?
А! Есть, есть вариант!
Надо обратиться к экстрасенсам, что бы они вам предсказывали график изменения цен на каждый лот, и тогда можно сразу эти данных за один раз кааак передааааать, и у клиента красиво и реалтаймово отрисовывать...
Осталась сущая малость - найти таких экстрасенсов. Ну с этим и сами справитесь, да?