Към съдържанието

Ръководства

Табла в реално време с Laravel, Redis и WebSockets

· 6 мин. четене

Laravel може да задвижва табла в реално време върху потоци с голям обем, ако суровите събития никога не стигат до браузъра: буферирайте приемането в Redis, обработвайте го в работни процеси (workers) от опашки, агрегирайте предварително във времеви интервали и излъчвайте през WebSockets само обобщения. Задавайте известия по динамични прагове, изведени от скорошната история, вместо по фиксирани граници, и добавете специализирана платформа за потоци, когато нуждите от повторно изпълнение, подредба или обем надраснат опашките в Redis.

Дръжте суровите събития далеч от браузъра

Най-честата грешка при таблата в реално време е всяко входящо събитие да се изпраща до всеки свързан екран. При голям обем браузърите изостават, WebSocket сървърът се претоварва, а графиката така или иначе става нечетима.

Разделете системата на четири етапа: приемане, обработка, агрегиране и излъчване. Всеки етап има собствен капацитет и може да се забави, без да повлече останалите. Таблото получава агрегирани обновявания в постоянен ритъм, например веднъж в секунда за всеки панел, а не сурови събития.

Нашите инженери използваха тази структура в Slump – платформа за наблюдение в реално време на тенденциите в 5G мрежите, показателите за капацитет и прогнозирането на претоварване за оператори в Южна Испания, изградена върху бекенд на Laravel 11 и 12, който приема поточни данни с голям обем.

Буферирайте приемането, за да не се превръщат пиковете на трафика в сривове

Крайната точка за приемане трябва да прави възможно най-малко: да валидира съдържанието, да го добави в буфер и да отговори. Разборът, обогатяването и записите в базата данни са работа на работните процеси.

При умерен обем Redis работи добре като такъв буфер. Добавяйте събитията в списък или поток (stream) в Redis и оставете работните процеси да ги изтеглят на партиди, защото едно партидно вмъкване е много по-евтино за базата данни от стотици вмъквания на отделни редове.

  • Валидирайте схемата и отхвърляйте неправилно оформените събития още на входа
  • Отговаряйте бързо и никога не записвайте в основната база данни по време на заявката
  • Четете от буфера на партиди, а не по едно събитие на задача
  • Ограничете дължината на буфера и настройте известие, когато расте, за да се вижда обратният натиск (backpressure), преди да доведе до загуба на данни

Мащабирайте обработката с отделни опашки и Horizon

Опашките на Laravel, поддържани от Redis, Ви дават работни процеси, които можете да добавяте хоризонтално. Laravel Horizon добавя брой работни процеси, пропускателна способност и време за изчакване за всяка опашка, и така проверявате дали обработката смогва с приемането.

Разделете опашките по приоритет. Оценката на известията никога не бива да чака зад натрупана повторна обработка на исторически данни, затова дайте на обработката, агрегирането, известията и експортите собствени опашки и групи работни процеси.

Направете всяка задача идемпотентна. Потоците доставят повторно, работните процеси се сриват по средата на партида и повторните опити се случват, затова двукратната обработка на едно и също събитие не бива да удвоява брояч. Често е достатъчен идентификатор на събитието, проверен срещу краткотрайно множество (set) в Redis.

Агрегирайте във времеви интервали, преди да излъчвате

Таблата показват честоти, средни стойности, перцентили и тенденции, а не отделни събития. Изчислявайте ги в работните процеси във фиксирани времеви интервали, например за секунда и за минута, за всеки обект, който показвате: клетка, регион, клиент.

Дръжте текущите агрегати в Redis, с хешове или сортирани множества с ключ по интервал, и записвайте всеки приключил интервал в базата данни за историята. Проектирането на заявките към тези исторически таблици е също толкова важно, колкото пътят на живо, защото потребителите ще поискат да видят цял ден или седмица.

В Slump преработката на кеширането с Redis и оптимизацията на заявките намалиха латентността при приемането на данни, което поддържаше изгледа на живо актуален при натоварване.

Излъчвайте обобщения през WebSockets с Reverb или хоствана услуга

Broadcasting в Laravel изпраща събития към канали, за които фронтендът се абонира чрез Laravel Echo. Laravel Reverb е собственият WebSocket сървър на Laravel, а хоствани услуги като Pusher или Ably работят през същия broadcasting API.

  • Излъчвайте по таймер от агрегираното състояние, а не веднъж за всяко входящо събитие
  • Използвайте частни канали и оторизирайте всеки абонамент на сървъра, за да виждат потребителите само обектите, които имат право да виждат
  • Изпращайте компактни моментни снимки или разлики, а не пълни набори от данни
  • При повторно свързване нека клиентът зареди текущото състояние през HTTP и след това да продължи потока
  • С нарастването на броя връзки пуснете няколко инстанции на Reverb зад балансьор на натоварването, с Redis pub/sub между тях

Задавайте известия по динамични прагове вместо по фиксирани граници

При поточни метрики фиксираните прагове се провалят и в двете посоки. Трафикът в 3 ч. през нощта изобщо не прилича на трафика в 20 ч., така че една-единствена граница или сработва цяла нощ, или пропуска проблемите през деня.

Динамичният праг сравнява всяка нова стойност с базово ниво, изведено от скорошната история за същия обект и същото време от седмицата. Проста и обяснима версия поддържа плъзгаща се средна стойност и стандартно отклонение за всеки обект и час от седмицата и вдига известие, когато стойността остане извън тази лента за няколко последователни интервала.

В Slump динамичните известия за аномалии намалиха ръчното наблюдение, защото операторите получаваха сигнал при реални отклонения, вместо да следят екраните.

  • Изисквайте устойчивост, например три последователни интервала извън лентата, за да намалите шума
  • Поддържайте едно отворено известие за обект и условие, което се обновява, а не се повтаря
  • Включвайте текущата стойност, базовото ниво, лентата и връзка към панела във всяко известие
  • Редовно преглеждайте заглушените и пренебрегнатите известия и настройвайте лентата

Знайте кога да добавите специализирана технология за потоци

Laravel с Redis покрива много, но има граници. Помислете за Kafka, Redpanda или управлявана услуга за потоци, често с процесор на потоци като Apache Flink, когато Ви трябват дълго съхранение и повторно възпроизвеждане на суровите събития, строга подредба по ключ при много консуматори или пропускателна способност, при която паметта на Redis става тясното място.

Преходът не е задължително да стане наведнъж. Запазете Laravel за API, таблата, управлението на известията и излъчването и поставете потока пред етапа на агрегиране. Изграждаме и разширяваме системи в реално време с такава структура – от приемането на данни до правилата за известия, на които операторите разчитат.

Основното накратко

  • Никога не изпращайте сурови събития към браузърите; излъчвайте агрегирани обобщения в постоянен ритъм.
  • Поддържайте крайната точка за приемане олекотена и буферирайте събитията в Redis за партидна обработка от работните процеси.
  • Разделете опашките по приоритет и направете всяка задача идемпотентна, за да не могат повторните опити да развалят броячите.
  • Динамичните прагове, основани на скорошната история, дават по-малко и по-полезни известия от фиксираните граници.
  • Добавете Kafka или подобна платформа, когато Ви трябват повторно възпроизвеждане, строга подредба или обем отвъд възможностите на Redis, и запазете Laravel за приложния слой.

Въпроси и отговори

Може ли Laravel да поддържа табла в реално време за данни с голям обем?

Да, когато архитектурата държи тежката работа извън пътя на заявката: олекотена крайна точка за приемане, буфер в Redis, работни процеси от опашки, които агрегират във времеви интервали, и излъчване през WebSockets само на обобщения. Тогава Laravel обслужва API, таблата и известията, а работните процеси се мащабират независимо.

Laravel Reverb или Pusher за WebSockets?

Reverb е собственият WebSocket сървър на Laravel и работи на Ваша инфраструктура, което е подходящо за екипи, които искат контрол върху разходите и местоположението на данните. Pusher или Ably премахват оперативната работа по поддръжката на WebSocket сървъри. И двата използват един и същ broadcasting API на Laravel, така че можете да смените по-късно.

Какво е динамичен праг при наблюдението?

Динамичният праг е граница за известие, изчислена от скорошната история за същата метрика, същия обект и същото време от седмицата, а не фиксирано число. Той се съобразява с дневните и седмичните модели, така че известията сработват при истински отклонения, а не при нормални пикове.

Кажете ни от какво имате нужда.

Нещо за изграждане, хора за намиране или въпрос, който чака отговор. В 30-минутен разговор Ви изслушваме и казваме честно как можем да помогнем и какво ще е нужно.