@verycooldev

Как сделать простой счетчик посещений?

Есть простой API сервер для SPA приложения. Стек: Нода, Экспресс, Монго.

Задача: простой счетчик количества запросов по определенному роуту (поскольку сам фронт отделен от API) неуникальных пользователей и сохранение этих данных. Т.е. каждое обращение считать, даже если юзер обновляет страницу (так же как и на Тостере).

И тут возникают вопросы как же это правильно реализовать?

1. Если при каждом обращении за данными изменять поле count в Монге для запрашиваемой статьи - это выглядит как-то слишком нагруженно на сервер
2. Что будет если одновременно запросит страницу (т.е. вернее роут, с которого страница потянет данные) 100, 500, 1000 человек? 1000 операций записи в БД одновременно? Как с этим на практике у Монги? Я полагаю данные либо будут терятся либо все умрет. Или они встанут в очередь и появится дикая задержка?
3. Может как-то хранить в памяти счетчик и потом периодически его сохранять в БД к нужной статье?

Вообщем, несмотря на простоту задачи, как ее эффективно выполнить ответа пока нету. Вчера гуглил полвечера и ответов не нашел. прошу помощи более опытных товарищей.
  • Вопрос задан
  • 1232 просмотра
Решения вопроса 2
teknik2008
@teknik2008
Расскажите про GOLANG. Мне интересно
Если ожидается большая нагрузка, то можно сделать шардирование бд или применить бд которые готовы в большим объемам записи (clickhouse).
Можно еще к примеру применить буферы, после наполнение, более 1000 записей, сразу всю пачку записать в бд. Но писать по 1-й строке в основную бд это очень дорого в точки зрения ресурсозатрат
Ответ написан
@napa3um
Сначала нужно делать "в лоб", просто увеличивать счётчик при запросе. Потом, когда проблема производительности реально возникнет, можно приступить к масштабированию схемы. Например, завести 10 (100, 1000) счётчиков, которые запросы инкрементируют, выбирая случайно любой из них, а при чтении их агрегировать (или с какой-то периодичностью в отдельный счётчик складывать агрегат). Подобная схема, в общем-то, применяется к любым данным, не только к счётчикам, для размазывания их по отдельным ресурсам (вычислительным узлам, таблицам, строкам), чтобы при записи не возникало конкуренции между запросами (а при чтении суммы счётчиков, как правило, не возникает лока на задеваемые ресурсы).

Минутка философии
Вообще, у хранилищ данных в информационной системе можно выделять две условные (не всегда чёткие) роли. OLTP - это хранилище, в которое приложение может быстро писать, там нужно делать минимум обработки, главное быстро сохранить данные и "отпустить" клиента (самый прямой пример такого хранилища - лог). И OLAP - это уже хранилище предвычисленных агрегатных данных, чтобы быстро отобразить их клиенту (а не вычислять во время запроса). И когда назревает необходимость масштабирования, эти роли начинают провляться всё явнее и явнее - приходится разделять этап приёма запроса и, собственно, его обработки, обработку откладывают на потом (складывают в очередь) настолько, насколько позволителен лаг между записью и актуализацией читаемых данных.
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
@frees2
Если больше 10 событий, юзер нажал, просмотрел 10 раз, к примеру, то отправляем на сервер, зато роботы всякие в пролёте.

var i = 0;(function(history){ var pushState = history.pushState;
history.pushState = function(state) { if (typeof history.onpushstate == "function")
{history.onpushstate({state: state});} 
return pushState.apply(history, arguments); }})(window.history);
window.onpopstate = history.onpushstate = function(e){ i++; test=JSON.stringify(e.state);  


if (localStorage.getItem('history666') === null) { document.getElementById("moo").innerHTML ='Нет в памяти!' ;   }

Или через localStorage, JSON данные куда нибудь в хранилище идёт.
Ответ написан
Ваш ответ на вопрос

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

Похожие вопросы