Логистические компании теряют клиентов из-за отсутствия прозрачности в доставке. Личный кабинет с real-time трекингом решает эту проблему - но только если архитектура выдержит нагрузку от тысяч одновременных пользователей. Команда ZORKA разработала систему отслеживания грузов, которая обрабатывает 50 тыс. GPS-событий в час без задержек.
Почему стандартные решения падают под нагрузкой реального трекинга
Типичный личный кабинет обновляет данные раз в 5-10 минут через REST API. Для логистики это неприемлемо - клиент видит устаревшую информацию, звонит в поддержку, и доверие падает. Real-time трекинг требует совсем другой архитектуры: WebSocket вместо HTTP, горячее кэширование вместо базы данных, географическая распределенность серверов.
При 500+ активных грузовиков одновременно классический стек (Node.js + PostgreSQL + REST) начинает тормозить. Каждый запрос о статусе - это обращение в базу, каждый ответ - это сетевой пакет. Получается бутылочное горлышко на уровне инфраструктуры, и никакой оптимизацией кода это не решишь.
Трекинг грузов в реальном времени требует архитектуры на WebSocket с in-memory хранилищем (Redis) и миграцией тяжелых операций на background-воркеры. REST API годится только для редких операций вроде поиска архивных доставок.
Как мы построили систему на 50K GPS-событий в час
Основу составил stack: Next.js 14 с API Routes для управления, Redis Streams для очереди GPS-данных, WebSocket-сервер на Node.js для real-time доставки клиентам. GPS-координаты приходят от терминалов через MQTT (оптимальный протокол для IoT), агрегируются в Redis, распределяются подписчикам через WebSocket в формате protobuf - это меньше трафика, чем JSON.
База данных (PostgreSQL с PostGIS) хранит только финальные данные: завершённые маршруты, статистику доставок, документооборот. Текущие координаты никогда не записываются в основную БД - только в Redis. Это разгружает диск и позволяет запросам работать в миллисекундах, а не в сотнях миллисекунд.
Разделите данные на три уровня: горячие (координаты в Redis, TTL 5 минут), теплые (статусы доставок в памяти App Server, TTL 30 минут), холодные (истории в PostgreSQL, запросы редко). Это даст вам и скорость, и надежность.
Интерфейс, который клиент понимает без подсказок
На карте каждый груз отображается с иконкой статуса: в пути, на сортировке, доставлен. Клиент видит время прибытия с погрешностью ±3 минуты (расчет из расстояния и исторических скоростей), маршрут с отклонениями от оптимального пути, историю обновлений. Все это грузится асинхронно, первый экран рисуется за 800 мс.
Мобильный интерфейс учитывает медленный 3G - карта грузится в low-res режиме, панели сжимаются, текст переносится. На слабом интернете приложение продолжает работать: новые координаты приходят медленнее, но не замораживают интерфейс. Тестировали на реальной нагрузке: 5000 одновременных юзеров на картах одновременно - медианная задержка 1.8 сек от события до клиента.
На картах никогда не анимируй движение всех грузов вместе - это замораживает браузер. Используй clustering (Leaflet Markercluster) для 50+ объектов и canvas-рендеринг для 500+ точек. Проверяй производительность через DevTools Performance tab с 6x CPU throttle.
Как система растёт от 100 до 5000 грузовиков в сутки
На 100 грузовиков хватает одного Redis-ноды (6GB памяти, ~100K IOPS) и одного Next.js-сервера. На 1000 грузовиков добавляем Redis Sentinel для failover и балансировщик нагрузки перед приложением. На 5000 грузовиков - Redis Cluster (3 ноды), кэш-слой Cloudflare для статических ассетов, CDN для карт и тайлов, разные инстансы для разных регионов РФ.
Интеграция с внешними системами ( 1С, SAP, собственные CRM) идет через REST API с rate limiting - 1000 запросов в час на клиента. Вебхуки на события (груз доставлен, отклонение от маршрута, задержка) отправляются асинхронно, с гарантией доставки и retry-логикой. Данные экспортируются через стандартный интерфейс: CSV, Excel, API JSON.
Прежде чем масштабировать инфраструктуру, профилируйте нагрузку: 80% вычислений обычно приходится на 2-3 операции. Оптимизируйте их, потом думайте про горизонтальное масштабирование. Слепой скейлинг - дорогой способ отбросить деньги.
Что показывать диспетчеру и как ловить проблемы до жалоб клиентов
Личный кабинет клиента - это фасад. За кулисами - дашборд для диспетчера с KPI: процент доставок без задержек, среднее время доставки по маршруту, количество GPS-сбоев, время отклика системы. Каждое отклонение от плана триггерит алерт: груз задерживается, водитель сделал неверный поворот, батарея GPS-трекера критична.
Логирование структурировано: каждый event (смена статуса, изменение маршрута, сетевая ошибка) записывается с timestamp, user ID, GPS-координатами, duration операции. Это позволяет быстро разобраться в инцидентах: медленный запрос - посмотрел логи, нашел проблему в интеграции с SAP. Мониторинг через Sentry ловит exceptions, DataDog отслеживает изменения performance.
Используйте структурированное логирование (JSON) с уровнями info, warning, error, debug. Индексируйте логи по user_id, delivery_id, status - это ускорит расследования в 10 раз. Настройте retention за 30 дней, остальное архивируйте в S3.
- Клиент видит координаты с задержкой 2-5 минут - теряет доверие к системе
- Каждый запрос об обновлении статуса - это вызов в БД, при 500 клиентах сервер падает
- Нет анализа аномалий маршрута - водитель сворачивает с оптимального пути, а система молчит
- Интеграция с CRM ручная или через cron-задачи каждый час - расхождения в данных
- Мобильный интерфейс зависает при обновлении данных, особенно на 3G
- Координаты обновляются в браузере за 1-2 секунды от GPS-события - прозрачность в реальном времени
- Горячие данные в Redis вместо БД - система справляется с 50K событий в час без lag
- Автоматическая детекция отклонений маршрута, задержек, GPS-сбоев через аналитику
- API интеграция синхронная - внешние системы видят актуальный статус доставки всегда
- Canvas-рендеринг карты на 500+ объектов, clustering на меньших масштабах - плавный UX даже на слабых девайсах
- Интервью с диспетчерами и водителями - понять болевые точки
- Анализ текущих потоков данных - откуда приходят координаты, как их используют
- Прототипирование интерфейса на Figma - какую информацию показать и в каком порядке
- Расчет нагрузки - количество грузовиков, частота обновлений, география
- Развертывание Redis Cluster и настройка Streams для GPS-событий
- Реализация WebSocket-сервера на Node.js с механизмом подписки на доставки
- REST API для управления доставками, интеграций, аналитики
- Система оповещений - алерты для диспетчера при отклонениях
- Компоненты Next.js: карта, панель доставок, фильтры, история статусов
- Подключение Leaflet с clustering и canvas-рендерингом
- Реализация WebSocket-клиента - слушание обновлений координат в реальном времени
- Оптимизация мобильного интерфейса - адаптация под 3G, кэширование
- Load-тестирование: 5000 одновременных клиентов на картах
- Настройка Sentry для ловли ошибок, DataDog для мониторинга производительности
- Интеграция с внешними системами (1С, SAP, если нужны)
- Миграция реальных данных, обучение диспетчеров, запуск в боевых условиях
Часто задаваемые вопросы
Используем фильтр Калмана для очистки шума GPS и комбинируем данные со слабого сигнала с предыдущей траекторией водителя. Если сигнал потеряется на несколько минут (тоннель, паркинг), система экстраполирует положение на основе скорости и истории маршрутов. Точность в городе обычно 10-15 метров, на магистралях 3-5 метров. Для критичных операций добавляем сверку с отметками времени на маршруте (прибытие на адрес).
Система автоматически анализирует отклонения: объезд пробки, поиск места парковки, остановка на заправке. Если отклонение меньше 5 минут от планового времени прибытия, показываем причину (выполняется остановка на маршруте), если больше - отправляем уведомление с обновленным ETA. В интерфейсе отображаются все запланированные остановки (сортировка, доп. доставки), поэтому клиент видит контекст отклонения.
Система уведомит диспетчера через 2 минуты молчания GPS (алерт в интерфейсе). Водитель может отправить update вручную через мобильное приложение или позвонить - оператор заносит информацию. В личном кабинете клиента груз переходит в статус 'Соединение потеряно' с последней известной позицией. Когда трекер снова подключится, система синхронизирует данные и восстанавливает маршрут на карте. Критичные грузы (ценности, скоропортящееся) контролируются дополнительно - водитель отправляет фото доставки и подпись получателя.
Redis Streams с асинхронной обработкой - GPS-события не блокируют друг друга, они накапливаются в очереди и обрабатываются параллельно на background-воркерах. WebSocket-соединения тоже асинхронные: обновления отправляются батчами каждые 100мс, а не поштучно. При скачке нагрузки на 30% сверх обычного горизонтальное масштабирование добавляет новый инстанс Redis (при Cluster конфигурации автоматическое перераспределение). В худшем случае - задержка вырастает с 1.8 сек до 4-5 сек, но система не падает и восстанавливается за минуты.
Готовы внедрить real-time трекинг?
Команда ZORKA проанализирует вашу текущую инфраструктуру, спроектирует архитектуру под вашу нагрузку и подготовит детальную смету за 2 дня. Затем - от 18 дней до полного запуска.