Jak wstrzymywać i kontrolować kolejki w Laravel krok po kroku

Ostatnia aktualizacja: 5 grudnia 2025
  • Laravel oferuje ujednolicony interfejs API kolejek z wieloma sterownikami (baza danych, Redis, SQS…) oraz rozdzieleniem połączeń i kolejek logicznych.
  • Zadania umożliwiają przeniesienie trudniejszych zadań do tła, zapewniając obsługę modeli serializacyjnych, oprogramowania pośredniczącego, zadań jednorazowych, szyfrowania, partii i ciągów.
  • Pracą zarządza się za pomocą poleceń queue:work, Supervisor oraz poleceń takich jak queue:pause/queue:continue, kontrolując ponowne próby, limity czasu i priorytety.
  • Dostępny jest kompletny ekosystem do obsługi błędów, monitorowania i testowania (failed_jobs, queue:retry, queue:monitor, Queue::fake), dzięki czemu kolejki są niezawodne w środowisku produkcyjnym.

Zarządzanie kolejkami w Laravel

Praca z kolejkami w Laravelu jest niemal obowiązkowa w każdym poważnym projekcie: wysyłaniu e-maili, przetwarzaniu plików CSV, generowaniu plików PDF, zmianie rozmiaru obrazów, wywoływaniu zewnętrznych interfejsów API… Jeśli wszystko to odbywa się w głównym żądaniu HTTP, strona internetowa staje się powolna, pojawia się 500 błędów, a użytkownik kończy z rozpaczliwym wpatrywaniem się w pusty ekran.

Dobra wiadomość jest taka, że ​​Laravel oferuje wydajną i elastyczną infrastrukturę kolejkową , która pozwala delegować większość zadań do procesów w tle, zarządzać nimi według priorytetów, grupować je w partie, monitorować, ponawiać próby w przypadku awarii, a nawet tymczasowo wstrzymywać procesy robocze na potrzeby konserwacji. Przyjrzyjmy się bliżej (i nie pomińmy niczego) temu, jak w pełni wykorzystać jej możliwości, w tym jak wstrzymywać, wznawiać i kontrolować jej działanie w środowisku produkcyjnym.

Podstawowe koncepcje: połączenia, kolejki i sterowniki

W Laravelu, zanim cokolwiek zatrzymasz, musisz zrozumieć różnicę między połączenia kolejkowe i same kolejki. W config/queue.php masz tablicę connections gdzie definiujesz każdy back-end: baza danych, redis, beanstalkd, sqs, synchronizacja, null, failover, rabbitmq (jeśli dodasz), itp.

Każde połączenie może mieć kilka kolejki logiczne (nazwy takie jak default, emails, high, low, importsAtrybut queue Każde połączenie wskazuje domyślną kolejkę, do której trafią zadania, jeśli nie zostanie określona żadna inna. onQueue()W ten sposób możesz wykonać następujące czynności:

  • Szybka kolejka do wiadomości e-mail lub krótkich transakcji.
  • Kolejny niski priorytet do długotrwałych zadań, takich jak przetwarzanie filmów wideo lub dużych raportów.
  • Kolejki segmentowane według typu zadania: imports, notificaciones, reportes, itp.

Kiedy uruchamiasz pracownika za pomocą php artisan queue:workDomyślnie nasłuchuje kolejki określonej jako domyślna na wybranym połączeniu. Jeśli chcesz nadać priorytet, możesz przekazać wiele kolejek rozdzielonych przecinkami:

php artisan queue:work redis --queue=high,default,low

W ten sposób pracownik najpierw przetwarza wiadomości o wysokim priorytecie , potem wiadomości domyślne , a na końcu wiadomości o niskim priorytecie , co jest szczególnie ważne, gdy system jest obciążony i nie chcesz, aby 30-minutowy raport blokował wiadomości o wysokim priorytecie.

Sterowniki kolejek i wymagania wstępne

Laravel oferuje ujednolicone API dla kilku sterowników kolejek , ale każdy z nich ma swoje specyficzne funkcje i zależności. Wybór odpowiedniego sterownika jest kluczowy przed omówieniem wstrzymywania procesów roboczych.

Baza danych kierowców

Kierowca baza danych Przechowuje zadania w tabeli SQL (zwykle jobsJest łatwy w konfiguracji i doskonale nadaje się do małych projektów lub środowisk programistycznych, w których nie chcesz bawić się z Redis lub SQS.

Podstawowe kroki:

  • Wygeneruj migrację: php artisan queue:table (lub w nowszych wersjach występuje jako create_jobs_table domyślny).
  • Uruchom migracje: php artisan migrate.
  • Konfiguruj QUEUE_CONNECTION=baza danych w .env i potwierdź w config/queue.php oferuje nasz konfigurator 'default' => env('QUEUE_CONNECTION','database').

Rozwiązanie to jest wygodne i dość solidne, ale przy wielu kolejkach i dużym ruchu może stać się wąskim gardłem , ponieważ wszystko przechodzi przez tę samą relacyjną bazę danych.

Sterownik Redis

Sterownik Redis to standardowy „koń roboczy” w środowisku produkcyjnym. Jest szybki, obsługuje zaawansowane funkcje (blokowanie, ograniczanie przepustowości, blokady atomowe, Horizon itp.) i bardzo dobrze się skaluje.

Ważne punkty:

  • Musisz skonfigurować połączenie Redis w config/database.php.
  • Opcje serializer y compression z Redis Nie są kompatybilne z kierowcą kolejki.
  • Jeśli używasz Klaster RedisNazwy kolejek muszą mieć znacznik hash, np. {default}tak, aby wszystkie klucze w kolejce trafiły do ​​tego samego slotu.
  • opcja block_for Umożliwia pracownikowi zablokowanie się na kilka sekund podczas oczekiwania na zadania, zamiast ciągłego sondowania: oszczędza procesor i redukuje liczbę zapytań do serwera Redis.

Na przykład:

'redis' => ,

Jeśli umieścisz blok_dla = 0Pracownik pozostaje zablokowany na czas nieokreślony, dopóki nie pojawi się nowe zadanie, o czym należy pamiętać, jeśli chcemy, aby szybko reagował na sygnały takie jak SIGTERM lub polecenia pauzy.

Inne sterowniki: SQS, Beanstalkd, null, failover…

Oprócz baz danych i Redis, Laravel obsługuje inne systemy :

  • Amazon SQSZarządzane kolejki w AWS z obsługą FIFOGrupy wiadomości, deduplikacja i zaawansowane ustawienia widoczności. Wymaga zestawu SDK. aws/aws-sdk-php.
  • Łodyga fasoliBardzo szybko i łatwo, korzystając z pakietu pda/pheanstalk.
  • synchronizować: wykonuje zadania natychmiast w tym samym procesie. Przydatne w rozwoju lub testowaniu, ale w środowisku produkcyjnym praktycznie nie używa się kolejek.
  • zero: Odrzuca zadania natychmiast po ich „wysłaniu”. Służy do całkowitego wyłączenia systemu kolejkowania.
  • praca awaryjnaPozwala to skonfigurować wiele połączeń, a jeśli połączenie główne zawiedzie, Laravel spróbuje przenieść zadanie do kolejnego na liście. Idealne rozwiązanie dla środowisk, w których duża dostępność jest krytyczny.
  Electron JS: Wszystko, co musisz wiedzieć

Na poziomie wstrzymywania i wznawiania pracy pracowników logika jest praktycznie taka sama, niezależnie od sterownika, ponieważ jest zarządzana z poziomu poleceń Artisan i klasy Worker , a nie z poziomu zaplecza kolejki.

Tworzenie zadań i serializacja modeli

Un Praca W Laravelu jest to po prostu klasa, która hermetyzuje zadanie do wykonania w kolejce. Zazwyczaj jest generowana za pomocą Artisana i zapisywana w app/Jobs.

Aby utworzyć:

php artisan make:job ProcessPodcast

Wygenerowana klasa narzędzia ShouldQueue i zwykle używa cech Dispatchable, InteractsWithQueue, Queueable y SerializesModelsSerce jest w metodzie handle()czyli to, co pracownik robi po otrzymaniu zadania.

Szczególnie potężną funkcją jest automatyczna serializacja modeli Eloquent . Po zaakceptowaniu modelu w konstruktorze zadania (Job), Laravel nie dodaje całego obiektu do kolejki, a jedynie jego identyfikator. Po przetworzeniu zadania rekonstruuje model z bazy danych z załadowanymi relacjami.

Typowy przykład (w pseudokodzie, aby uniknąć powtarzania dosłownie):

  • Budowniczy otrzymuje Podcast $podcast.
  • Cecha SerializesModels Odpowiada za zapisanie ID.
  • En handle(AudioProcessor $processor) Ty wykonujesz ciężką pracę (np. przetwarzanie dźwięku).

Jeśli nie chcesz, aby relacje w modelu były serializowane (aby ładunek nie był ogromny), możesz użyć $model->withoutRelations() lub w PHP 8 atrybut # na nieruchomości reklamowanej przez dewelopera.

Wstrzykiwanie zależności w metodę handle

Kolejną zaletą jest to, że możesz wstrzykiwać usługi bezpośrednio do metody handle (jakby to był kontroler), ponieważ Laravel również korzysta z kontenera usług w zadaniach. Na przykład możesz zażądać AudioProcessorKlienci HTTP, repozytoria itp., a framework zajmuje się ich rozwiązywaniem.

Jeśli potrzebujesz ultra-precyzyjnej kontroli nad tym, co nazywa się handlemożesz użyć Container::bindMethod() u dostawcy usług i samodzielnie zdefiniować logikę wstrzykiwania, ale w większości przypadków nie ma potrzeby aż tak komplikować spraw.

Oprogramowanie pośredniczące w pracy

Tak jak trasy mają oprogramowanie pośredniczące, tak i zadania mogą mieć określonego oprogramowania pośredniczącego które są uruchamiane przed i po wykonaniu zadania. To znacznie zmniejsza liczbę powtarzających się kodów w metodach. handle() i jest szczególnie przydatny do:

  • Ograniczanie szybkości z Redis.
  • uniknąć nakłada się prac, które poruszają ten sam temat.
  • Zwykłe wyjątki dla niestabilnych interfejsów API.
  • Pomijanie zadań w pewnych okolicznościach (Skip (oprogramowanie pośredniczące).

Oprogramowanie pośredniczące jest zwykle umieszczane w app/Jobs/Middleware i są zwracane z metody middleware() Z Księgi Hioba. Przykład koncepcyjny:

public function middleware(): array { return ;

Specjalne typy zadań: unikalne, zaszyfrowane i zablokowane

Laravel umożliwia oznaczanie określonych zadań jako wyjątkowy aby zapewnić, że nigdy nie będzie dwóch identycznych instancji w kolejce w tym samym czasie. Osiąga się to poprzez implementację interfejsu ShouldBeUnique o ShouldBeUniqueUntilProcessingi obsługuje definiowanie klucza uniqueId() i czas uniqueFor.

Jest to idealne rozwiązanie w przypadku:

  • Przelicz indeks wyszukiwania produktu: tylko raz na produkt aż się skończy.
  • Synchronizacje z usługami zewnętrznymi, które nie pozwalają na jednoczesne żądania tego samego zasobu.

Poniżej Laravel używa blokada atomowa pamięci podręcznej (Redis, Memcached, baza danych itp.). Możesz również wybrać sterownik pamięci podręcznej dla tej blokady za pomocą uniqueVia().

Ponadto istnieje interfejs ShouldBeEncrypted, w którym wskazujesz, że Praca jest kompletna Wprowadź swój kod przed wejściem do kolejkiBardzo przydatne, gdy przesyłasz poufne dane i nie chcesz, aby były przesyłane w postaci zwykłego tekstu przez Redis, SQS lub bazę danych.

Wysyłaj, opóźniaj i wykonuj zadania w różnych trybach

Po zdefiniowaniu zadania należy je uruchomić za pomocą Job::dispatch() z kontrolerów, nasłuchiwaczy zdarzeń, poleceń Artisan, a nawet zamknięć. Parametry, które przekazujesz dispatch Udają się bezpośrednio do budowniczego Hioba.

Ciekawe warianty:

  • dispatchIf() y dispatchUnless() do kondycjonowania przesyłki w jednej linii.
  • delay() tak, że zadanie nie może zostać przetworzone do określonej daty/godziny.
  • dispatchAfterResponse() o afterResponse() en dispatch() Zamknięcia, które odraczają wykonanie do momentu wysłania odpowiedzi HTTP, ale w ramach tego samego procesu PHP.
  • dispatchSync() aby uruchomić zadanie synchronicznie (bez przechodzenia przez kolejkę), ale ponownie wykorzystując tę ​​samą klasę.
  • Połączenia specjalne takie jak deferred o background do wykonania po otrzymaniu odpowiedzi, w tym samym procesie lub w nowym procesie PHP.

Na koniec możesz określić połączenie i kolejkę za pomocą metod łańcuchowych onConnection() y onQueue(), zarówno podczas wysyłania, jak i w kreatorze zadań.

Dokładna kontrola: ponowne próby, wycofywanie, przekroczenia limitu czasu i obsługa błędów

Dużą częścią pracy z kolejkami w Laravel jest decydowanie, ile razy ponawiać próby wykonania zadania , jak długo czekać między kolejnymi próbami i kiedy uznać zadanie za niepowodzenie.

  Kim jest front-end developer i czym się zajmuje?

Dysponenci opcji:

  • --tries en queue:work aby ustawić maksymalną liczbę prób dla wszystkich zadań danego pracownika (chyba że zadanie definiuje własne) $tries o tries()).
  • $tries lub metoda tries() w klasie Job dla kontroli na poziomie Job.
  • retryUntil() powiedzieć: „próbuj tak wiele razy, ile chcesz, aż do tego momentu, potem to już porażka”. Jeśli to się pokrywa z tries, polecenie retryUntil.
  • $maxExceptions przerwać działanie, gdy problem wynika z powtarzających się nieobsłużonych wyjątków.
  • $timeout o --timeout aby wskazać, ile sekund może trwać zadanie, zanim pracownik zakończy proces potomny.
  • $failOnTimeout aby oznaczyć zadanie jako nieudane w przypadku przekroczenia limitu czasu.
  • $backoff metoda backoff() aby określić, jak długo czekać pomiędzy kolejnymi próbami, nawet przy wartościach wykładniczych.

Jeśli zadanie wygeneruje nieobsłużony wyjątek, Laravel... uwalnia się z powrotem do ogona aż do wyczerpania skonfigurowanych prób. Możesz to kontrolować ręcznie za pomocą release($segundos) o fail($exception) gdy chcesz celowo oznaczyć zadanie jako nieudane.

Nieudane zadania, tabela failed_jobs i przycinanie

Kiedy Hiob wyczerpie swoje możliwości, zaczyna być uważany za nieudana praca a Laravel wstawia to do tabeli failed_jobs (lub w DynamoDB, jeśli tak to skonfigurujesz). Ta tabela przechowuje identyfikator UUID, połączenie, kolejkę, ładunek zadania i zgłoszony wyjątek.

Przydatne polecenia:

  • php artisan queue:failed aby wymienić te, które nie powiodły się.
  • php artisan queue:retry <id|all> aby spróbować je ponownie.
  • php artisan queue:forget <id> aby usunąć jeden.
  • php artisan queue:flush aby usunąć wszystko (z opcją godzin w nowszych wersjach).
  • php artisan queue:prune-failed --hours=48 aby automatycznie usuwać stare rekordy.

W zadaniach możesz zdefiniować metodę failed(Throwable $exception) W celu dodatkowego czyszczenia: powiadom użytkownika, przywróć częściowe działania, zapisz specjalistyczne dzienniki itp. Należy pamiętać, że tworzona jest nowa instancja zadania, aby wywołać failed()Dlatego nie należy polegać na zmianach właściwości dokonanych w handle().

Partie zadań: partie zadań i łączenie ich za pomocą ciągów znaków

Gdy musisz uruchomić setki lub tysiące powiązanych ze sobą zadań (na przykład importowanie dużych plików CSV w częściach, przetwarzanie plików w partiach, czyszczenie danych itd.), zaleca się skorzystanie z funkcji przetwarzania wsadowego Laravela .

Podstawowy przepływ:

  • Utwórz tabelę job_batches z php artisan queue:batches-table && php artisan migrate.
  • Oznacz zadania, które będą częścią partii z cechą Batchable.
  • Użyj Bus::batch() aby wysłać zestaw zadań z wywołaniami zwrotnymi then, catch y finally.
  • Uzyskaj dostęp do partii z każdego zadania za pomocą $this->batch() i sprawdź czy zostało anulowane.
  • Możliwość dodania większej liczby zadań do trwającej partii za pomocą $this->batch()->add().

Partie idealnie integrują się z łańcuchami : łańcuchy mogą być częścią partii lub partie mogą być elementami większego łańcucha. Jest to szczególnie przydatne, gdy chcesz, aby wiele łańcuchów działało „równolegle” i uruchamiało coś po zakończeniu wszystkich operacji.

Wykonywanie zadań przez pracowników, priorytety i rozmieszczenie

Cała magia kolejek dzieje się, ponieważ masz jeden lub więcej pracowników uruchomienie polecenia queue:work (o queue:listen(choć ten drugi jest mniej wydajny). Procesy te to długotrwałe demony, które nasłuchują swoich kolejek.

Kluczowe opcje queue:work:

  • połączenie: php artisan queue:work redis, queue:work database, itp.
  • Colas: --queue=high,default,low ustalać priorytety.
  • -jedenaście: przetwarza pojedyncze zadanie i wychodzi.
  • –max-jobs: przetwarza zadania X i kończy działanie (aby okresowo ponownie uruchamiać procesy robocze i zwalniać pamięć).
  • –max-time: przetwarza przez N sekund, a następnie wychodzi.
  • -spać: sekund oczekiwania, gdy nie ma dostępnych zadań.
  • –zatrzymaj-gdy-pusty: opróżnia kolejkę i zamyka się czysto (idealne rozwiązanie w środowiskach Docker lub przy jednorazowych zadaniach).
  • – limit czasu: sekund limitu czasu dla każdego zadania, jak wspomnieliśmy wcześniej.
  • -siła:przetwarzanie zadań nawet wtedy, gdy aplikacja znajduje się w trybie konserwacji.

Ponieważ procesy te są długotrwałe, w środowisku produkcyjnym monitor procesów , taki jak Supervisor (w systemie Linux), jest prawie zawsze używany do uruchamiania procesów X, ponownego uruchamiania ich w przypadku awarii oraz zarządzania logami. Typowy blok konfiguracyjny Supervisora ​​dla Laravela definiuje:

  • komenda z php artisan queue:work ... beton.
  • numproc aby wskazać, ile pracowników ma zostać uruchomionych równolegle.
  • Ścieżki dziennika, użytkownik, automatyczne ponowne uruchamianie itp.

Wstrzymywanie i wznawianie kolejek w Laravel

Przejdźmy do tego, co często jest ważne w konserwacji: jak wstrzymywać pracowników kolejki bez ich nagłego zatrzymywania i bez pozostawiania niedokończonych zadań. Laravel oferuje kilka mechanizmów, zarówno nowszych, jak i klasycznych, które pozwalają to kontrolować.

Pauza: kolejka: sygnały pauzy i przerwania

W najnowszych wersjach Laravel dodaje konkretne polecenia wstrzymujące i wznawiające wykonywanie procesów roboczych:

  • php artisan queue:pause: informuje system, aby zaprzestał przyjmowania nowych zadań, ale pozwolił dokończyć te, które są już w toku.
  • php artisan queue:continue: wznawia przetwarzanie nowych zadań od miejsca, w którym zostało przerwane.
  Obliczanie współczynnika inflacji wariancji (VIF) w języku C# i projektowaniu oprogramowania

Te polecenia działają poprzez wysyłanie sygnałów do procesów roboczych za pośrednictwem mechanizmu buforowania, którego Laravel używa wewnętrznie. Dlatego ważne jest, aby mieć poprawnie skonfigurowany sterownik buforowania (Memcached, Redis, baza danych, plik itp.), nawet jeśli Twoja kolejka buforowania jest inna.

Ważne: Wstrzymanie kolejki lub pracownika nie powoduje anulowania ani usunięcia zadań, które już znajdują się w kolejce ; zapobiega jedynie usuwaniu kolejnych zadań z kolejki, dopóki trwa wstrzymanie.

Badanie zakłóceń i wpływu na wydajność

Za każdym razem, gdy pracownik kończy zadanie, Laravel sprawdza pamięć podręczną pod kątem sygnałów restartu, pauzy lub kontynuacji . Koszt takiego działania jest znikomy, ale występuje. Jeśli zależy Ci na wydajności i wiesz, że nie będziesz musiał wstrzymywać ani restartować pracowników z poziomu poleceń, możesz wyłączyć tę funkcję, wywołując:

Queue::withoutInterruptionPolling();

Lub nawet dostosować właściwości statyczne Illuminate\Queue\Worker aby wyłączyć określone dotknięcia ($restartable, Można wstrzymaćJeśli jednak to zrobisz i spróbujesz użyć queue:pause o queue:restartpracownicy Oni się nie dowiedząJest to decyzja projektowa, którą należy dokładnie rozważyć.

Wstrzymaj ręcznie za pomocą Supervisora ​​lub Dockera

Oprócz własnych poleceń Laravela , w środowiskach produkcyjnych procesy są często „wstrzymywane” pośrednio:

  • Zatrzymanie programu w programie Supervisor (supervisorctl stop laravel-worker:*), co powoduje śmierć lub zatrzymanie pracowników.
  • za pomocą –zatrzymaj-gdy-pusty wdrożeń, aby umożliwić pracownikom dokończenie tego, co jest w kolejce, a następnie wyłączenie.
  • W Dockerze pozwolenie kontenerowi na przetwarzanie za pomocą --stop-when-empty a potem się wyłącza.

Różnica z queue:pause Całkowite zatrzymanie procesów spowoduje wstrzymanie przetwarzania zadań do czasu ponownego uruchomienia pracowników. wewnętrzna pauza Możesz zachować procesy w pamięci, czekając na polecenie continueJest to przydatne w przypadku szybkich wdrożeń wycofujących lub krótkich okresów konserwacji.

Transakcje w bazie danych i after_commit

Klasyczny błąd: wysyłanie zadań w ramach transakcji bazy danych . Jeśli nie zachowasz ostrożności, pracownik może wykonać zadanie przed zatwierdzeniem, a oczekiwany model lub dane mogą jeszcze nie znaleźć się w bazie danych.

Aby uniknąć tego tańca, masz dwie możliwości:

  • aktywować 'after_commit' => true w konfiguracji połączenia kolejki. W ten sposób każde zadanie wysłane w ramach transakcji jest wewnętrznie odkładane do momentu potwierdzenia.
  • Stosuj metody per-job afterCommit() o beforeCommit() podczas wysyłania, aby wymusić określone zachowanie tylko w określonych zadaniach.

Jeżeli transakcja zostanie odwrócona, zadania wysłane w jej trakcie zostaną odrzucone i nie będą trafiać do kolejki, co jest zazwyczaj pożądane w celu zachowania spójności.

Monitorowanie, czyszczenie kolejek i testowanie

Gdy już kolejki działają na dobre, nie wystarczy po prostu wyrzucić zadań i zapomnieć o nich; należy monitorować i testować zachowanie wszystkich funkcji.

Przydatne narzędzia i polecenia:

  • queue:clear aby opróżnić konkretną kolejkę (SQS, Redis, baza danych).
  • queue:monitor aby monitorować liczbę zadań w określonych kolejkach i wyzwalać zdarzenie QueueBusy jeśli przekroczą próg.
  • Wydarzenia zawodowe jako Queue::before, Queue::after, Queue::looping y Queue::failing aby podłączyć niestandardową logikę (logi, metryki, wycofywanie zmian itp.).
  • Podróbki w testach przy Queue::fake() y Bus::fake() aby sprawdzić, czy zadania, ciągi znaków lub partie zostały wysłane bez ich faktycznego wykonywania.

W testach można określić takie rzeczy, jak „to zadanie zostało umieszczone w kolejce X razy” , „łańcuch tych zadań został wysłany w tej kolejności” lub „żadne konkretne zadanie nie zostało umieszczone w kolejce”, co zapewnia wysoki poziom bezpieczeństwa w złożonych przepływach.

Dzięki całemu ekosystemowi — sterownikom takim jak Redis lub SQS, dobrze zaprojektowanym zadaniom, oprogramowaniu pośredniczącemu do precyzyjnego dostrajania, partiom, łańcuchom, konfiguracji ponawiania prób, pracownikom zarządzanym przez przełożonego i poleceniom takim jak queue:pause y queue:continue— Laravel umożliwia sterowanie przetwarzaniem w tle w najdrobniejszych szczegółach, od typowego wysyłania wiadomości e-mail po rozproszone architektury kolejek z funkcją failover. Dzięki temu Twoja aplikacja będzie nadal szybko reagować na poziomie HTTP, podczas gdy w tle wykonywane są ciężkie zadania, nie blokując użytkownika.

Struktura Laravel
Podobne artykuły:
Potężny framework Laravel