Kolejki zadań — kiedy są potrzebne w aplikacji webowej
Kolejka zadań pozwala aplikacji odpowiedzieć użytkownikowi natychmiast, a ciężką pracę wykonać w tle. To rozwiązanie problemu, który w każdym rosnącym systemie pojawia się prędzej czy później: pewne operacje trwają zbyt długo, żeby użytkownik mógł na nie czekać, i są zbyt ważne, żeby pozwolić im się nie udać po cichu.
Krótka odpowiedź: kolejka zadań to mechanizm, w którym aplikacja zamiast wykonać operację od razu, zapisuje polecenie do wykonania, a osobny proces odbiera je i realizuje w tle. Użytkownik dostaje odpowiedź natychmiast.
Wdrażaj ją, gdy operacja trwa dłużej niż kilka sekund, zależy od usługi zewnętrznej albo musi zostać wykonana także wtedy, gdy coś chwilowo nie działa.
Problem, który rozwiązuje
Klient klika „złóż zamówienie". Aplikacja zapisuje zamówienie, wysyła potwierdzenie mailem, tworzy przesyłkę u przewoźnika, wystawia dokument sprzedaży i powiadamia magazyn. Wykonane po kolei, w trakcie jednego żądania, trwa to kilkanaście sekund — a użytkownik patrzy na kręcące się kółko i zaczyna klikać ponownie.
Gorzej: jeśli usługa przewoźnika akurat nie odpowiada, całe żądanie kończy się błędem. Zamówienie, które było poprawne, nie zostaje złożone z powodu awarii systemu trzeciej strony.
Kolejka rozdziela te dwie rzeczy. Aplikacja robi to, co niezbędne do odpowiedzi — zapisuje zamówienie — a resztę zleca do wykonania w tle. Użytkownik dostaje potwierdzenie w ułamku sekundy, a pozostałe czynności wykonują się niezależnie, z możliwością ponowienia przy niepowodzeniu.
Kiedy wdrożyć kolejkę
| Sytuacja | Czy kolejka | Uzasadnienie |
|---|---|---|
| Wysyłka wiadomości e-mail | Tak | Serwer pocztowy bywa wolny i bywa niedostępny |
| Generowanie dokumentu lub raportu | Tak | Czas rośnie z ilością danych |
| Wywołanie zewnętrznego API | Tak | Nie kontrolujesz dostępności ani czasu odpowiedzi |
| Przetwarzanie obrazu lub pliku | Tak | Obciąża procesor, blokuje obsługę innych żądań |
| Synchronizacja z systemem magazynowym | Tak | Musi się wykonać także po chwilowej awarii |
| Powiadomienia masowe | Tak | Rozłożenie w czasie zamiast jednego uderzenia |
| Zapis rekordu do bazy | Nie | Szybkie i wymagane do odpowiedzi |
| Sprawdzenie uprawnień | Nie | Wynik potrzebny natychmiast |
| Walidacja formularza | Nie | Użytkownik czeka na wynik |
Prosta reguła: jeśli użytkownik potrzebuje wyniku operacji, żeby móc iść dalej — wykonaj ją od razu. Jeśli operacja jest konsekwencją jego działania, ale on sam na nią nie czeka — do kolejki.
Ponawianie — sedno całego mechanizmu
Główna wartość kolejki nie polega na tym, że coś dzieje się w tle, lecz na tym, że nieudane zadanie można powtórzyć. Wymaga to jednak zaprojektowania kilku rzeczy.
Rosnący odstęp między próbami
Ponawianie natychmiast po niepowodzeniu zwykle prowadzi do kolejnego niepowodzenia i dokłada obciążenia usłudze, która ma problem. Odstęp powinien rosnąć: kilkanaście sekund, minuta, pięć minut, kwadrans.
Limit prób i miejsce docelowe
Zadanie, które nie powiodło się po kilku próbach, musi trafić na osobną listę do przejrzenia przez człowieka — nie znikać z dziennika. Ta lista to jedno z najważniejszych miejsc do codziennego sprawdzania.
Odporność na powtórzenie
To najczęściej pomijany wymóg. Zadanie może zostać wykonane dwa razy — na przykład gdy pierwsza próba się powiodła, ale potwierdzenie nie dotarło. Skutki muszą być takie same jak przy jednym wykonaniu.
Praktycznie oznacza to sprawdzenie przed działaniem: czy dokument już istnieje, czy wiadomość już wysłano, czy przesyłka ma już numer. Bez tego klient dostanie dwa maile i dwie faktury.
Uwaga praktyczna: pytanie „co się stanie, jeśli to zadanie wykona się dwa razy" należy zadać przy każdym zadaniu wstawianym do kolejki. Jeśli odpowiedź brzmi „byłby problem", zadanie wymaga zabezpieczenia, zanim trafi na produkcję.
Kolejność wykonania
Kolejka nie gwarantuje, że zadania wykonają się w tej samej kolejności, w jakiej zostały dodane — zwłaszcza gdy pracuje kilka procesów równolegle. Przy niezależnych czynnościach to bez znaczenia, ale przy powiązanych bywa źródłem trudnych do wykrycia błędów.
Jeśli kolejność ma znaczenie — na przykład aktualizacja stanu musi nastąpić po utworzeniu produktu — masz trzy możliwości: połączyć operacje w jedno zadanie, użyć osobnej kolejki obsługiwanej pojedynczo albo zaprojektować zadanie tak, żeby samo sprawdzało, czy warunki są spełnione, i odkładało wykonanie, gdy nie są.
Widoczność dla użytkownika
Praca w tle rodzi pytanie, skąd użytkownik ma wiedzieć, że coś się dzieje i czy się udało. Zignorowanie tego prowadzi do zgłoszeń w rodzaju „zamówiłem raport i nic nie przyszło".
- Natychmiastowe potwierdzenie przyjęcia — „raport jest przygotowywany, powiadomimy Cię".
- Widoczny status zadania tam, gdzie użytkownik może go sprawdzić.
- Powiadomienie o zakończeniu, jeśli operacja trwa dłużej niż moment.
- Czytelna informacja o niepowodzeniu z możliwością ponowienia — cisza jest najgorszym wariantem.
- Ochrona przed wielokrotnym zleceniem tego samego zadania przez niecierpliwego użytkownika.
Co monitorować
Kolejka działająca w tle ma tę właściwość, że jej awarię łatwo przeoczyć — aplikacja odpowiada normalnie, a zadania po prostu się nie wykonują.
- Długość kolejki. Rosnąca oznacza, że zadania przychodzą szybciej, niż są przetwarzane.
- Czas oczekiwania od dodania do wykonania.
- Liczba zadań nieudanych i tempo jej narastania.
- Czy proces przetwarzający w ogóle działa. Zatrzymany bez alertu bywa wykrywany po dniach.
- Zadania wykonujące się nietypowo długo — sygnał zapętlenia albo problemu z zależnością.
Pułapki wdrożeniowe
- Brak listy zadań nieudanych. Bez niej porażki znikają w dzienniku i nikt się nie dowiaduje, że część klientów nie dostała potwierdzeń.
- Zadanie zależne od kontekstu żądania. Wykonuje się później, więc nie ma dostępu do sesji użytkownika ani do danych, które istniały tylko w pamięci.
- Przekazywanie całych obiektów zamiast identyfikatorów. Dane bywają nieaktualne w momencie wykonania — lepiej przekazać identyfikator i pobrać stan bieżący.
- Brak limitu czasu. Zadanie zawieszone na wywołaniu zewnętrznym blokuje proces na godziny.
- Wszystko w jednej kolejce. Masowa wysyłka powiadomień opóźnia pilne zadania. Warto rozdzielić według priorytetu.
- Wdrożenie w trakcie przetwarzania. Proces musi umieć dokończyć bieżące zadanie przed zatrzymaniem, zamiast urywać je w połowie.
Czego użyć
Przy niewielkiej skali wystarczy kolejka oparta na tabeli w bazie danych, którą już masz — zadanie to wiersz, proces w tle odbiera najstarsze niewykonane. Rozwiązanie proste, przejrzyste i wystarczające dla większości systemów firmowych.
Wyspecjalizowane narzędzia kolejkowe stają się potrzebne, gdy zadań są dziesiątki tysięcy dziennie, gdy potrzebujesz rozbudowanych priorytetów albo gdy z kolejki korzysta kilka niezależnych aplikacji. Wcześniejsze sięganie po nie dokłada element infrastruktury do utrzymania, nie rozwiązując problemu, którego jeszcze nie masz.
Ta sama zasada obowiązuje przy wyborze architektury całego systemu — pisaliśmy o niej w materiale o mikroserwisach i monolicie. Warto też zajrzeć do tekstu o monitoringu aplikacji, bo kolejka bez obserwacji jest miejscem, w którym problemy narastają najciszej.
Zadania cykliczne a kolejka
Obok zadań wywoływanych działaniem użytkownika istnieje druga kategoria: czynności wykonywane regularnie — nocna synchronizacja, generowanie raportu miesięcznego, przypomnienia o kończącym się terminie. Warto rozumieć, czym różnią się od kolejki i jak je łączyć.
Różnica w wyzwalaczu
Kolejkę uruchamia zdarzenie — ktoś coś zrobił. Zadanie cykliczne uruchamia zegar. W praktyce najlepiej sprawdza się połączenie: harmonogram wstawia zadania do tej samej kolejki, z której korzysta reszta systemu. Zyskujesz jeden mechanizm ponawiania, jedną listę niepowodzeń i jeden monitoring.
Typowe błędy przy zadaniach cyklicznych
- Brak zabezpieczenia przed nakładaniem. Zadanie uruchamiane co godzinę, które trwa półtorej, uruchomi się drugi raz przed zakończeniem pierwszego. Potrzebna jest blokada.
- Przetwarzanie wszystkiego naraz. Nocne zadanie obejmujące cały zbiór danych rośnie razem z nim i pewnego dnia nie zdąży przed rankiem. Lepiej przetwarzać porcjami.
- Cisza przy niepowodzeniu. Zadanie, które przestało się wykonywać, bywa wykrywane dopiero wtedy, gdy ktoś zauważy brak raportu.
- Zależność od strefy czasowej serwera. Zmiana czasu potrafi spowodować pominięcie lub podwójne wykonanie.
Praktyczna zasada: każde zadanie cykliczne powinno zostawiać ślad wykonania z datą, a brak tego śladu przez zakładany czas powinien uruchamiać powiadomienie. Bez tego zatrzymane zadanie milczy tygodniami.
Warto na koniec zauważyć, że kolejka zmienia sposób myślenia o systemie. Przestaje on być jedną sekwencją kroków wykonywaną od początku do końca, a staje się zbiorem operacji, z których każda może się nie udać i zostać powtórzona niezależnie od pozostałych. To wymaga innej dyscypliny przy projektowaniu, ale daje odporność, której układ sekwencyjny nie osiągnie — awaria jednego elementu przestaje przewracać całość.
Podsumowanie
Kolejka zadań jest jednym z tych elementów, które w małym systemie wydają się przesadą, a w rosnącym okazują się niezbędne. Moment jej wprowadzenia rozpoznasz po objawach: żądania trwające zbyt długo, operacje przerywane przez awarie usług zewnętrznych, wiadomości, które czasem nie dochodzą bez wyraźnej przyczyny.
Zaczynając, zacznij od najprostszego wariantu opartego na własnej bazie i od jednego zadania — najlepiej wysyłki wiadomości, bo jest łatwa do sprawdzenia i najczęściej zawodzi. Przy tym jednym zadaniu przećwiczysz wszystkie mechanizmy, które będą potrzebne dalej: ponawianie, odporność na powtórzenie, listę niepowodzeń i monitoring.
Najczęstsze pytania
To mechanizm, w którym aplikacja zamiast wykonywać czasochłonną operację od razu, zapisuje polecenie do wykonania, a osobny proces odbiera je i realizuje w tle. Użytkownik dostaje odpowiedź natychmiast, a operacja wykonuje się niezależnie, z możliwością ponowienia przy niepowodzeniu.
Wysyłkę wiadomości, generowanie dokumentów i raportów, wywołania zewnętrznych interfejsów, przetwarzanie plików oraz synchronizację z systemami zewnętrznymi. Reguła jest prosta: jeśli użytkownik potrzebuje wyniku, żeby iść dalej — wykonaj od razu; jeśli nie czeka na wynik — do kolejki.
Powinno zostać ponowione z rosnącym odstępem czasu, a po wyczerpaniu limitu prób trafić na osobną listę do przejrzenia przez człowieka. Kluczowe jest, żeby nieudane zadania nie znikały w dzienniku — bez widocznej listy niepowodzeń nikt nie zauważy, że część operacji nie została wykonana.
Bo może wykonać się dwa razy — na przykład gdy pierwsza próba się powiodła, ale potwierdzenie nie dotarło i mechanizm ponowił operację. Bez zabezpieczenia klient otrzyma dwie wiadomości i dwa dokumenty. Rozwiązaniem jest sprawdzenie przed działaniem, czy skutek już nie zaistniał.
Przy niewielkiej skali wystarczy kolejka oparta na tabeli w bazie danych, którą już masz. Wyspecjalizowane narzędzia stają się potrzebne przy dziesiątkach tysięcy zadań dziennie, rozbudowanych priorytetach albo gdy z kolejki korzysta kilka niezależnych aplikacji.
Convert Studio realizuje projekty z tego obszaru dla firm w całej Polsce. Zobacz: Aplikacje webowe → · Lokalizacje →
Bezpłatna wycena Twojego projektu
Opisz w kilku zdaniach, co chcesz zbudować — stronę, aplikację czy sklep. Odpowiadamy w ciągu 24 godzin roboczych konkretną propozycją zakresu i harmonogramu. Konsultacja i wycena są bezpłatne, bez zobowiązań.