Представьте: карточка товара показывает «Сейчас смотрят 42 человека», а реальных посетителей на сайте — три. Из-за ботов и неоптимизированного счётчика данные искажаются, доверие падает, а сервер захлёбывается запросами. Мы настраивали такой механизм десятки раз — от небольших каталогов до проектов с миллионом посетителей в месяц. Подход должен быть быстрым, правдоподобным и не нагружать сервер. Экономия на серверных ресурсах при использовании Redis вместо MySQL — до 40%.
Типичные проблемы: устаревшие данные (если обновлять раз в минуту — цифры теряют актуальность), нагрузка на БД при каждом запросе, искажение статистики ботами. Без правильной фильтрации ботов счетчик может показывать 100+ «человек», когда реальных посетителей единицы. Оптимальное окно активности — 5–10 минут, а минимальный порог вывода — 2 человека.
Как определить «сейчас смотрят»
Понятие «смотрит прямо сейчас» — условное. На практике считают пользователей, открывших страницу товара за последние 2–15 минут (магазин выбирает окно самостоятельно). Типичный выбор: 5–10 минут.
Для хранения активных просмотров используется одна из двух стратегий: Вариант 1 — таблица в MySQL/PostgreSQL. Создаётся таблица bl_product_viewers:
CREATE TABLE bl_product_viewers ( id INT AUTO_INCREMENT PRIMARY KEY, product_id INT NOT NULL, session_id VARCHAR(64) NOT NULL, last_seen DATETIME NOT NULL, INDEX idx_product_time (product_id, last_seen) ); При каждом просмотре вставляется или обновляется запись по (product_id, session_id). Для подсчёта: SELECT COUNT(DISTINCT session_id) WHERE product_id = ? AND last_seen > NOW() - INTERVAL 5 MINUTE. Агент раз в 10 минут чистит устаревшие записи.
Вариант 2 — Redis. Ключ viewers:product:{id} — это sorted set, где score = timestamp последнего визита, member = session_id. Подсчёт: ZCOUNT viewers:product:123 (NOW-300) +inf. Устаревшие записи удаляются через ZREMRANGEBYSCORE. Это быстрее и не нагружает БД, но требует Redis на сервере.
Почему стоит использовать Redis?
Redis обеспечивает скорость записи и чтения менее 1 мс, что критично при тысячах одновременных просмотров. Он не нагружает MySQL, храня данные в оперативной памяти. Это снижает расходы на серверные ресурсы и ускоряет отклик AJAX-запросов.
Как реализовать на стороне Битрикс
В component_epilog.php детальной страницы товара записывается визит:
$productId = $arResult["ID"]; $sessionId = session_id(); $now = date("Y-m-d H:i:s"); $DB->Query("INSERT INTO bl_product_viewers (product_id, session_id, last_seen) VALUES (" . intval($productId) . ", '" . $DB->ForSql($sessionId) . "', '" . $now . "') ON DUPLICATE KEY UPDATE last_seen = '" . $now . "'"); Подсчёт активных просмотров выносится в отдельный AJAX-контроллер — не стоит делать SELECT в epilog, иначе каждый запрос страницы будет тормозить на чтении.
Подробнее о работе с component_epilog.
Как реализовать AJAX-обновление счётчика
Счётчик обновляется на клиенте без перезагрузки страницы. JavaScript-компонент делает запрос каждые 30–60 секунд:
setInterval(() => { fetch('/ajax/product-viewers/?id=' + productId) .then(r => r.json()) .then(data => { if (data.count > 1) { document.querySelector('.viewers-count').textContent = 'Сейчас смотрят: ' + data.count; } }); }, 30000); AJAX-обработчик в Битрикс регистрируется через CModule::AddAutoloadClasses() или как отдельный PHP-файл с включением ядра через require $_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/main/include/prolog_before.php'.
Как исключить ботов из счётчика?
Ботов фильтруют по User-Agent в component_epilog.php перед записью. Используйте регулярное выражение, проверяющее наличие строк bot, crawler, spider и т.д. в заголовке. Это обязательный шаг — без него цифры завышаются на 30–40%. Для встроенных механизмов Битрикс можно использовать BITRIX_SESSID и проверку IsUserAuthorized, но это не защищает от поисковых ботов.
Пошаговая инструкция настройки
- Выбор хранилища: MySQL или Redis. Для малых проектов подойдёт MySQL, для высоконагруженных — Redis.
- Создание структуры данных: таблицы или Sorted Set в Redis.
- Регистрация визита: в
component_epilog.phpс фильтрацией ботов. - AJAX-контроллер: возвращает JSON с количеством активных просмотров.
- Клиентский JS: обновляет счётчик каждые 30 секунд.
- Агент очистки: для MySQL — SQL-запрос, для Redis —
EXPIREили фоновая очистка. - Настройка порогов и склонений: для красивого вывода.
Сравнение способов хранения
| Параметр | MySQL/PostgreSQL | Redis |
|---|---|---|
| Скорость записи | ~5 ms | <1 ms |
| Скорость чтения | ~3 ms (с индексом) | <0.5 ms |
| Нагрузка на сервер | Средняя (диск I/O) | Низкая (RAM) |
| Требования | База данных | Установка Redis |
| Масштабируемость | Горизонтально | Вертикально |
Этапы настройки
| Этап | Описание | Время |
|---|---|---|
| Анализ | Выбор окна активности, определение нагрузки | 2 часа |
| Проектирование | Выбор хранилища (MySQL/Redis), схема таблицы | 1 час |
| Реализация | Запись визитов, AJAX-контроллер, JS-компонент | 4-6 часов |
| Тестирование | Проверка с ботами, нагрузочное тестирование | 2 часа |
| Деплой | Размещение агента, настройка кэширования | 1 час |
Что входит в настройку
- Создание таблицы
bl_product_viewers(или настройка Redis-ключей) - Запись визитов в
component_epilog.phpс фильтрацией ботов - AJAX-контроллер для получения актуального количества просмотров
- JavaScript-компонент с периодическим обновлением счётчика
- Агент для очистки устаревших записей
- Вывод блока с правильными условиями (порог, склонение)
Обращайтесь к нам — мы реализуем этот механизм под ключ за 1–3 дня. Наша команда имеет более 5 лет опыта с 1С-Битрикс и десятки успешных проектов с кастомными счётчиками. Закажите настройку — получите рабочий счётчик за 24 часа. Получите консультацию по вашему магазину.
Свяжитесь с нами для консультации.







