Kolejka zadań pozwala wykonywać zadania poza bezpośrednią ścieżką obsługi żądania: wysyłać powiadomienia, przetwarzać pliki lub synchronizować dane. Gdy jednak napływa więcej zadań, niż konsumenci są w stanie wykonać, tworzy się backlog. Opóźnienia mogą być widoczne jako późne potwierdzenia, nieaktualne dane lub zadania, które nigdy się nie kończą. Wpływa to zarówno na użytkowników, jak i zespoły obsługujące aplikację.
Aby zdecydować, jak postąpić, nie wystarczy sprawdzić, ile wiadomości oczekuje na przetworzenie. Znaczenie mają ich wiek, tempo napływu i realizacji, rodzaj zadań oraz stan zależności. Dodanie konsumentów może pomóc, jeśli przepustowość jest niewystarczająca, ale może też zwielokrotnić liczbę zapytań do już przeciążonej bazy danych. Bezpieczne działanie zaczyna się od pomiarów i rozpoznania wzorca.
Co ujawnia backlog i jakich metryk brakuje

Liczba oczekujących zadań to migawka, a nie wyjaśnienie. Może wzrosnąć podczas skoku obciążenia, a potem zmniejszyć się bez interwencji albo pozostać stabilna, podczas gdy najstarsze zadanie czeka coraz dłużej. Dlatego oceniając, jak kontrolować backlog kolejki PHP, warto obserwować łącznie:
- Tempo napływu: liczbę przyjętych zadań w jednostce czasu.
- Tempo przetwarzania: liczbę zadań ukończonych w jednostce czasu, z rozróżnieniem ukończonych zadań i nieudanych prób.
- Wiek: czas oczekiwania najstarszego zadania, a także percentyle czasu oczekiwania, jeśli są dostępne.
- Czas przetwarzania: czas realizacji poszczególnych typów zadań i zmiany tego czasu.
- Błędy i ponowne próby: odsetek niepowodzeń, liczbę prób oraz obecność zadań przekazanych do kolejki błędów lub kwarantanny.
- Stan konsumentów i zależności: aktywne procesy, restarty, użycie CPU i pamięci, połączenia z bazą danych oraz opóźnienia usług zewnętrznych.
Tempo przetwarzania powinno odzwierciedlać liczbę rzeczywiście ukończonych zadań: liczenie każdej próby jako przetworzonego zadania może ukryć cykl błędów i ponownych prób. Ważne jest też segmentowanie danych według kolejki lub klasy zadań. Średnia globalna może maskować sytuację, w której jeden typ zadań blokuje pozostałe.
Rozpoznaj wzorzec, zanim zmienisz przepustowość
Porównaj metryki w przedziale czasowym odpowiednim dla danej operacji i z typowym zachowaniem systemu. Wzorce pomagają ukierunkować analizę, ale same w sobie nie dowodzą przyczyny.
- Tempo napływu stale przewyższa tempo przetwarzania: przepustowość może być niewystarczająca, mógł wzrosnąć wolumen albo wydłużyć się czas realizacji zadań. Sprawdź ostatnie zmiany, skład ruchu i czasy dla poszczególnych typów zadań.
- Konsumenci są aktywni, ale przetwarzanie niemal nie postępuje: szukaj zablokowanych procesów, niekończącego się oczekiwania, deadlocków, wyczerpania puli połączeń lub wywołań zewnętrznych bez limitów czasu. Sprawdź logi i ślady powiązane identyfikatorem zadania.
- Wydłużają się czas realizacji i opóźnienia zależności: konsumenci mogą czekać na bazę danych, API lub pamięć masową. Więcej procesów może zwiększyć rywalizację o zasoby i pogorszyć opóźnienia.
- Te same zadania wielokrotnie kończą się niepowodzeniem: przyczyną mogą być nieprawidłowe dane, sytuacja, której nie da się naprawić przez ponowienie próby, lub błąd. Sprawdź politykę ponownych prób: ponawianie ich zbyt szybko może wywołać lawinę obciążenia.
- Jedna kolejka rośnie, podczas gdy inne są przetwarzane: sprawdź priorytety, rozdział konsumentów oraz to, czy jedna klasa zadań nie monopolizuje zasobów.
Sprawdź również ostatnie zmiany konfiguracji i wdrożenia. Upewnij się, że telemetria odróżnia zajętego konsumenta od działającego procesu, który nie robi postępów; sprawdzenie, czy proces jest aktywny, nie gwarantuje ukończenia zadań.
Oszacuj tempo opróżniania kolejki na podstawie obserwacji
Jeśli utrzymujące się tempo przetwarzania przewyższa tempo napływu, kolejka może się zmniejszać, o ile ta różnica się utrzyma. Jako przybliżenie operacyjne można przyjąć, że czas przetworzenia backlogu zależy od liczby oczekujących zadań podzielonej przez efektywne tempo opróżniania: tempo przetwarzania minus tempo napływu w tym samym okresie. Jeśli ta różnica wynosi zero lub jest ujemna, samo wydłużenie czasu oczekiwania nie rozwiąże narastania zaległości.
To przybliżenie jest wskazówką operacyjną, a nie obietnicą terminu przywrócenia działania. Zakłada, że tempo pozostanie stałe, a zadania będą miały podobny skład i koszt. Kilka długotrwałych zadań, ponowne próby lub ograniczenia zależności mogą zmienić wynik. Korzystaj z tempa obserwowanego przy rzeczywistym obciążeniu i ponownie szacuj je po każdej interwencji. W przypadku zadań o różnym koszcie obliczaj je osobno dla każdej klasy albo mierz czas obsługi, a nie tylko liczbę wiadomości.
Interweniuj etapami i w określonych granicach
W pierwszej kolejności wybieraj działania odwracalne i ograniczone zakresem. Zanim zmienisz liczbę konsumentów, ustal, jakie obciążenie może tolerować każda zależność i jak wycofać zmianę.
- Jeśli to możliwe, ogranicz napływ nowych zadań: wstrzymaj nieistotnych producentów, wprowadź limity lub odłóż zadania o niskim priorytecie. Nie odrzucaj zadań bez reguły biznesowej, rejestru i mechanizmu odzyskiwania.
- Odizoluj problematyczne zadania: ogranicz liczbę prób, stosuj rosnące opóźnienia, gdy jest to uzasadnione, i kieruj trwałe niepowodzenia do kolejki błędów, którą można przejrzeć. Nie ignoruj tych zadań: mogą wymagać poprawienia i ponownego przetworzenia.
- Chroń priorytety: oddziel zadania pilne od konserwacyjnych lub masowego przetwarzania i sprawdź, czy priorytety nie skazują mniej pilnych kolejek na niekończące się oczekiwanie.
- Stopniowo dostosowuj współbieżność: zmieniaj liczbę konsumentów małymi krokami i obserwuj przepustowość oraz przeciążenie. Utrzymuj limity zgodne z dostępną liczbą połączeń, CPU, pamięcią i limitami usług zewnętrznych.
- Usuń przyczynę: jeśli problemem są wolne zapytania, blokady lub wywołania bez timeoutu, usuń to wąskie gardło, zanim pozostawisz więcej procesów działających równolegle.
Idempotencja jest szczególnie ważna, gdy zadanie może zostać wykonane więcej niż raz. Projektuj operacje na systemach zewnętrznych i zapisy tak, aby tolerowały ponowne próby, albo stosuj odpowiednie mechanizmy deduplikacji. Ustal również, co się stanie, jeśli konsument zatrzyma się po wykonaniu operacji, ale przed potwierdzeniem wiadomości.
Ustal progi i procedurę odzyskiwania
Ustalaj progi na podstawie wymagań dotyczących poziomu usług, a nie uniwersalnej wartości liczbowej. Alert może łączyć maksymalny wiek zadań lub percentyl czasu oczekiwania, trend backlogu, różnicę między tempem napływu a przetwarzania oraz odsetek błędów. Wiek zadań zwykle lepiej odzwierciedla wpływ na użytkownika niż sama liczba; wolumen pomaga oszacować skalę problemu.
Udokumentuj, kto interweniuje, które kolejki można wstrzymać, z jakimi zależnościami należy się skonsultować i które zmiany wymagają zatwierdzenia. Podczas incydentu zapisuj czas, hipotezę, działanie i zaobserwowany efekt. Po każdej korekcie sprawdź, czy tempo przetwarzania wzrosło bez niedopuszczalnego wzrostu opóźnień bazy danych, błędów usług zewnętrznych, zużycia zasobów lub liczby awarii aplikacji.
Uznaj odzyskanie działania za potwierdzone, gdy wiek i wolumen zadań stale maleją, zadania są poprawnie kończone, a zależności wracają do stabilnego poziomu. Nie ogłaszaj rozwiązania problemu tylko dlatego, że licznik spada: wiadomości mogły zostać odrzucone lub nagromadzić się w innej kolejce.
Lista kontrolna zapobiegająca kolejnym zaległościom

- Czy dla każdej kolejki mierzone są napływ, użyteczne przetwarzanie, wiek, czas realizacji i ponowne próby?
- Czy zadania mają limity czasu oraz skończoną i odpowiednią politykę ponownych prób?
- Czy alerty sygnalizują brak postępu, a nie tylko duży wolumen?
- Czy maksymalna współbieżność uwzględnia limity współdzielonych zależności?
- Czy można odizolować problematyczną klasę zadań bez zatrzymywania całego przetwarzania?
- Czy istnieje udokumentowana procedura bezpiecznego wstrzymywania, wznawiania i ponownego przetwarzania?
- Czy po zmianach kodu, obciążenia lub konfiguracji analizuje się metryki i skutki uboczne?
Zdrowa kolejka nie musi być pusta: wahania mogą być normalne. Praktycznym kryterium jest kończenie zadań w ramach zakładanego poziomu usług, widoczność błędów i zachowanie przez system zapasu pozwalającego absorbować skoki obciążenia. Pomiar tego zachowania umożliwia podjęcie działań, zanim zaległości przerodzą się w przerwę w świadczeniu usług dla użytkowników.



