Comparthing Logo
kolejkowanie wiadomościwzorce niezawodnościsystemy rozproszonearchitektura chmurowaobsługa błędówinfrastruktura chmurowa

Kolejki martwych listów a ponowne próby w pamięci

Kolejki martwych komunikatów i ponawianie prób w pamięci to dwa zasadniczo różne podejścia do radzenia sobie z błędami przetwarzania komunikatów w systemach rozproszonych. Kolejki DLQ zapewniają trwałą izolację problematycznych komunikatów, podczas gdy ponawianie prób w pamięci oferuje lekkie odzyskiwanie danych z niskim opóźnieniem i bez obciążenia trwałością.

Najważniejsze informacje

  • Kolejki martwych wiadomości przechowują nieudane wiadomości w nieskończoność, co czyni je niezbędnymi w scenariuszach audytu i zgodności
  • Ponowne próby w pamięci są wykonywane z narzutem rzędu mikrosekund w porównaniu z opóźnieniami rzędu milisekund w przypadku operacji w kolejce
  • DLQ umożliwiają oddzielnym zespołom operacyjnym zarządzanie awariami bez konieczności wdrażania zmian w kodzie aplikacji
  • Burze ponownych prób z podejść w pamięci mogą wywołać kaskadowe awarie, jeśli nie są ograniczone wyłącznikami

Czym jest Kolejki martwych listów?

Trwałe kolejki komunikatów, które wychwytują błędne komunikaty w celu ich późniejszej kontroli i ponownego przetworzenia.

  • Wiadomości przeniesione do DLQ po przekroczeniu maksymalnych progów ponownych prób, zachowując pełną treść wiadomości i metadane
  • Początkowo spopularyzowany przez systemy obsługi wiadomości korporacyjnych, takie jak IBM MQ i JMS, obecnie standardowy w AWS SQS, Azure Service Bus i RabbitMQ
  • Umożliwiaj odseparowaną analizę awarii bez blokowania głównych procesów przetwarzania, umożliwiając zespołom rozwiązywanie problemów i odtwarzanie komunikatów
  • Zwykle integrują się z systemami monitorowania i ostrzegania, aby powiadamiać operatorów, gdy wiadomości przejdą w stan martwych listów
  • Obsługa zasad wygasania opartych na czasie, z domyślnym przechowywaniem wiadomości przez 14 dni w usłudze AWS SQS DLQ

Czym jest Ponowne próby w pamięci?

Logika natychmiastowych ponownych prób wykonywana w tym samym procesie bez zewnętrznego utrwalania komunikatów.

  • Zasady ponawiania prób zwykle stosują wykładniczy czas oczekiwania, w którym opóźnienia między próbami podwajają się (np. 1 s, 2 s, 4 s, 8 s)
  • Takie struktury jak Polly (.NET), Resilience4j (Java) i Retry (Python) zapewniają konfigurowalne strategie ponawiania prób z wzorcami wyłączników
  • Nie zużywaj żadnych dodatkowych zasobów infrastruktury poza istniejącą pamięcią i procesorem aplikacji przetwarzającej
  • Całkowita awaria aplikacji w trakcie ponownej próby powoduje utratę stanu ponownej próby i potencjalnie oryginalnego kontekstu operacji.
  • Najlepiej nadaje się do stosowania w przypadku przejściowych awarii, takich jak przerwy w działaniu sieci, przekroczenia limitu czasu połączenia z bazą danych i tymczasowa niedostępność usług

Tabela porównawcza

Funkcja Kolejki martwych listów Ponowne próby w pamięci
Trwałość Trwałe przechowywanie wiadomości w osobnej kolejce Ulotny, istnieje tylko w pamięci aplikacji
Odzyskiwanie po awarii Przetrwa awarie aplikacji i ponowne uruchomienia Utracone, jeśli proces zakończy się podczas ponownej próby
Koszt infrastruktury Dodatkowe koszty przechowywania i transferu w kolejce Brak dodatkowej infrastruktury poza aplikacją
Widoczność operacyjna Wbudowane metryki, alarmy i możliwości odtwarzania Wymaga niestandardowego rejestrowania i monitorowania
Wpływ opóźnienia Większe opóźnienie z powodu operacji kolejkowych Minimalne opóźnienie, natychmiastowe ponawianie próby wykonania
Dopasowanie przypadku użycia Krytyczne przepływy pracy wymagające gwarantowanego przetwarzania Operacje niekrytyczne z przejściowymi awariami
Porządkowanie wiadomości Może zachować lub zakłócić oryginalną kolejność Utrzymuje naturalną sekwencję procesów
Współpraca zespołowa Umożliwia osobną własność zespołu w celu naprawy i ponownego odtwarzania Ściśle powiązane z wdrażaniem aplikacji

Szczegółowe porównanie

Gwarancje niezawodności i trwałości

Kolejki martwych wiadomości sprawdzają się doskonale, gdy nie ma absolutnie żadnej możliwości utraty wiadomości. Gdy wiadomość trafi do DLQ, pozostaje tam, dopóki ktoś nie zajmie się nią w sposób jawny, nawet po ponownym uruchomieniu całej usługi. Z kolei ponawianie prób w pamięci znika bez śladu, jeśli kontener ulegnie awarii lub proces zostanie zatrzymany podczas wdrażania. To sprawia, że DLQ są oczywistym wyborem w przypadku transakcji finansowych, aktualizacji zapasów lub wszelkich innych kwestii związanych z zapewnieniem zgodności.

Charakterystyka wydajności i opóźnień

Ponawianie prób w pamięci zdecydowanie wygrywa pod względem szybkości. Nie ma przeskoków sieciowych, wywołań API kolejek, narzutu serializacji, tylko szybkie uśpienie i ponowna próba. W przypadku systemów o wysokiej przepustowości przetwarzających tysiące komunikatów na sekundę ta różnica jest ogromna. DLQ wprowadzają mierzalne opóźnienie, zwłaszcza gdy komunikaty muszą przekroczyć granice sieci, aby dotrzeć do oddzielnej usługi kolejkowania. Niektóre zespoły stosują hybrydyzację, wykorzystując ponawianie prób w pamięci do szybkich, przejściowych poprawek, a DLQ jako ostateczną siatkę bezpieczeństwa.

Złożoność operacyjna i debugowanie

DLQ tworzą wyraźną granicę operacyjną. Twój dyżurny inżynier zostaje przekierowany, sprawdza kolejkę niedostarczonych wiadomości, naprawia błąd i odtwarza wiadomości. To dobrze znany przepływ pracy. Ponawianie prób w pamięci powoduje, że awarie są ukrywane w logach aplikacji, często wymagając agregacji logów i niestandardowych pulpitów nawigacyjnych, aby w ogóle wiedzieć, że próby są powtarzane. Wyczerpanie się możliwości ponawiania prób to koszmar programu do rozwiązywania awarii, szczególnie w mikrousługach, gdzie awaria może przenieść się kaskadowo, zanim ktokolwiek ją zauważy.

Rozważania nad kosztami w dużej skali

Usługi kolejkowania w chmurze naliczają opłaty za każde żądanie i zapisaną wiadomość. Obciążona kolejka DLQ milionami wiadomości może znacząco wpłynąć na rachunek, szczególnie jeśli zasady retencji są hojne. Ponawianie prób w pamięci jest zasadniczo bezpłatne z punktu widzenia infrastruktury, choć zużywa pamięć i może powodować niedobór zasobów w innych wątkach, jeśli burze prób nie są ograniczone. W przypadku startupów, na których zależy na kosztach, często skłania to szalę w kierunku podejścia w pamięci, dopóki przychody nie uzasadnią dodatkowej niezawodności.

Integracja z nowoczesnymi architekturami

Architektury sterowane zdarzeniami i funkcje bezserwerowe sprawiły, że zapytania DLQ stały się bardziej istotne niż kiedykolwiek. AWS Lambda, Azure Functions i Google Cloud Functions natywnie obsługują konfiguracje z martwymi komunikatami. Ponawianie prób w pamięci lepiej wpisuje się w tradycyjne serwery aplikacji i długotrwałe procesy. Rozwój Kubernetesa i obliczeń efemerycznych skomplikował strategie w pamięci – kontenery mogą zostać zamknięte z niewielkim ostrzeżeniem, co sprawia, że zapytania DLQ stają się coraz bardziej atrakcyjne nawet dla zespołów, które wcześniej ich unikały.

Zalety i wady

Kolejki martwych listów

Zalety

  • + Gwarantowana trwałość przekazu
  • + Wyraźne przekazanie operacyjne
  • + Natywna integracja z chmurą
  • + Obsługuje odtwarzanie i audyt
  • + Izoluje wpływ awarii

Zawartość

  • Dodatkowy koszt infrastruktury
  • Większe opóźnienie między końcami
  • Wymaga mechanizmu odtwarzania
  • Może gromadzić nieaktualne wiadomości
  • Bardziej złożona architektura

Ponowne próby w pamięci

Zalety

  • + Bardzo niskie opóźnienie
  • + Brak dodatkowej infrastruktury
  • + Łatwe do wdrożenia na początku
  • + Minimalne koszty operacyjne
  • + Szybka informacja zwrotna o awarii

Zawartość

  • Zagubiony w wyniku awarii procesu
  • Ukryte przed operacjami
  • Może powodować burze ponownych prób
  • Ścisłe powiązanie z cyklem życia aplikacji
  • Trudniej debugować retrospektywnie

Częste nieporozumienia

Mit

Kolejki martwych komunikatów eliminują potrzebę stosowania jakiejkolwiek logiki ponawiania prób w aplikacjach.

Rzeczywistość

DLQ są celem po wyczerpaniu limitu ponownych prób, a nie zastępują logiki ponownych prób. Większość implementacji nadal wykonuje natychmiastowe lub opóźnione próby, zanim uzna komunikat za martwy. Bez pośrednich prób, każdy przejściowy błąd natychmiast zalałby DLQ.

Mit

Ponawianie operacji w pamięci jest zawsze szybsze i dlatego zapewnia lepszą wydajność.

Rzeczywistość

Chociaż pojedyncze próby są szybsze, nieograniczone próby w pamięci mogą nasycić pule wątków i obniżyć ogólną przepustowość systemu. Przewaga wydajnościowa szybko znika, gdy burze prób uruchamiają wyłączniki lub przeciążają usługi podrzędne.

Mit

Wiadomości znajdujące się w kolejkach martwych listów są później automatycznie przetwarzane.

Rzeczywistość

DLQ to pasywne miejsce przechowywania, z tymi wiadomościami nic się nie dzieje, dopóki nie nastąpi wyraźne działanie człowieka lub automatu. Wiele zespołów odkryło wiadomości sprzed miesięcy zalegające w DLQ, ponieważ nikt nie zbudował potoku odtwarzania.

Mit

Należy wybierać wyłącznie pomiędzy DLQ i ponownymi próbami w pamięci.

Rzeczywistość

Te wzorce doskonale się uzupełniają. Najbardziej odporne systemy wykorzystują ponawianie prób w pamięci z wykładniczym odliczaniem czasu do szybkiego odzyskiwania, a następnie eskalują do DLQ po przekroczeniu rozsądnego progu. To warstwowe podejście obejmuje zarówno przejściowe, jak i trwałe tryby awarii.

Mit

Ponawianie prób w pamięci nie jest odpowiednie dla systemów rozproszonych.

Rzeczywistość

Choć mniej niezawodne niż DLQ, ponawianie prób w pamięci pozostaje powszechne i odpowiednie w systemach rozproszonych do idempotentnych, niekrytycznych operacji. Kluczem jest dopasowanie strategii ponawiania prób do rzeczywistych konsekwencji biznesowych awarii, a nie zakładanie jednego schematu pasującego do wszystkich.

Mit

Kolejki martwych wiadomości zapobiegają utracie wiadomości podczas przerw w działaniu systemu.

Rzeczywistość

DLQ pomagają tylko w przypadku wiadomości już zaakceptowanych przez system kolejkowania. Jeśli wiadomość nigdy nie dotrze do kolejki głównej z powodu partycji sieciowej lub awarii producenta, DLQ nie będzie w stanie jej magicznie odzyskać. Niezawodność typu end-to-end wymaga również trwałości po stronie producenta.

Często zadawane pytania

Co dokładnie powoduje przeniesienie wiadomości do kolejki martwych wiadomości?
Wiadomości zazwyczaj trafiają do kolejki DLQ po wyczerpaniu skonfigurowanych prób ponownych prób, co może oznaczać przekroczenie maksymalnej liczby odbiorów w SQS, niepowodzenie dostarczenia do wielu odbiorców lub jawne odrzucenie przez kod aplikacji. Dokładny wyzwalacz różni się w zależności od platformy. AWS SQS korzysta z zasady ponownego przesyłania, która określa maksymalną liczbę odbiorów, podczas gdy Azure Service Bus śledzi liczbę dostarczonych wiadomości. Po przekroczeniu tego progu infrastruktura przesyłania wiadomości automatycznie przenosi lub kopiuje wiadomość do powiązanej kolejki martwych wiadomości.
W jaki sposób ponawianie prób w pamięci radzi sobie z ponownymi uruchomieniami i awariami procesów?
Nie działają, co stanowi ich fundamentalne ograniczenie. Każdy stan ponawiania istnieje wyłącznie w stercie działającego procesu. Jeśli aplikacja ulegnie awarii, zostanie zamknięta podczas wdrażania lub kontener zostanie przeplanowany, wszystkie oczekujące ponowienia i ich kontekst znikną. W przypadku operacji, które muszą przetrwać takie zdarzenia, potrzebne są trwałe mechanizmy ponawiania, niezależnie od tego, czy jest to DLQ, kolejka zadań oparta na bazie danych, czy rozproszone systemy zadań, takie jak Celery lub Hangfire.
Czy można łączyć kolejki martwych komunikatów z ponownymi próbami w pamięci w tym samym systemie?
Zdecydowanie, i jest to w rzeczywistości najlepsza praktyka dla wielu zespołów. Typowy schemat obejmuje ponawianie prób w pamięci z wykładniczym odczekiwaniem w celu natychmiastowego odzyskania danych przejściowych, powiedzmy, trzy próby w ciągu kilku sekund. Jeśli te się nie powiodą, wiadomość lub operacja jest publikowana w kolejce z obsługą DLQ w celu zapewnienia trwałego przetwarzania. Zapewnia to szybkość ponawiania prób w pamięci w przypadku błędów i bezpieczeństwo DLQ w przypadku problemów trwałych.
Jakie monitorowanie należy skonfigurować w przypadku kolejek martwych wiadomości?
Skonfiguruj co najmniej alarmy dotyczące głębokości kolejki, wieku najstarszej wiadomości i szybkości wiadomości przychodzących. Nagły wzrost liczby wiadomości przychodzących DLQ zazwyczaj wskazuje na wdrożony błąd. Alerty dotyczące wieku wiadomości wychwytują przypadki, w których nie następuje odtwarzanie. Wiele zespołów śledzi również stosunek liczby wiadomości DLQ do liczby wiadomości pomyślnie przetworzonych jako wskaźnik kondycji. CloudWatch, Azure Monitor lub Datadog mogą wyświetlać te metryki dzięki integracji z pagerem.
Czy istnieją alternatywy dla DLQ i ponawiania prób w pamięci?
Kilka wzorców zaspokaja podobne potrzeby. Wzorzec skrzynki nadawczej transakcyjnie utrwala zdarzenia z danymi biznesowymi, zapewniając atomowość. Wzorzec Saga zarządza długotrwałymi transakcjami rozproszonymi z akcjami kompensującymi. Kolejki zadań oparte na bazie danych, takie jak Sidekiq lub pg-boss, oferują trwałość bez dedykowanych brokerów komunikatów. Źródło zdarzeń rekonstruuje stan z dziennika tylko do dopisywania, co zmienia semantykę ponawiania prób. Właściwy wybór zależy od wymagań dotyczących spójności i istniejącej infrastruktury.
Jak bezpiecznie odtworzyć wiadomości z kolejki martwych listów?
Nigdy nie odtwarzaj komunikatów DLQ bezpośrednio do oryginalnej kolejki bez inspekcji, ponieważ prowadzi to do nieskończonych pętli, jeśli przyczyna problemu nadal występuje. Zamiast tego, przenieś komunikaty DLQ do oddzielnego środowiska analitycznego, zbadaj reprezentatywne próbki, aby zidentyfikować wzorzec awarii, napraw przyczynę problemu, a następnie selektywnie odtwarzaj komunikaty w partiach z monitorowaniem. AWS oferuje funkcje odtwarzania DLQ, a narzędzia takie jak Amazon EventBridge Pipes mogą automatyzować przepływy pracy z warunkowym odtwarzaniem.
Jakie są dobre zasady ponawiania prób w pamięci?
Wykładniczy backoff z jitterem to złoty standard. Bez jittera zsynchronizowane próby od wielu klientów mogą powodować problemy z odzyskiwaniem usług. Ogranicz maksymalne opóźnienie, aby zapobiec nieograniczonym oczekiwaniom i zawsze ustaw maksymalną liczbę prób. Rozważ zastosowanie wyłączników, które całkowicie zatrzymają próby, gdy wskaźniki awarii przekroczą progi, dając czas usługom podrzędnym na odzyskanie sprawności, zamiast obciążać je w czasie awarii.
Czy funkcje bezserwerowe dobrze współpracują z ponownymi próbami w pamięci?
Nie do końca. Funkcje Lambda i podobne są zaprojektowane tak, aby były bezstanowe i krótkotrwałe. Maksymalny czas wykonania wynoszący piętnaście minut oznacza, że okno ponawiania prób w pamięci jest ograniczone. Co ważniejsze, jeśli Lambda się nie powiedzie, cały kontekst wykonania znika. Architektury bezserwerowe zdecydowanie preferują stan zewnętrzny, co sprawia, że zapytania DLQ lub funkcje krokowe z wbudowaną logiką ponawiania prób są znacznie bardziej naturalne niż podejścia oparte na pamięci.
Jakie są różnice w podejściu do kwestii kolejności komunikatów?
Kolejki DLQ mogą komplikować gwarantowanie kolejności. Jeśli główna kolejka to FIFO, przenoszenie wiadomości do i z kolejki DLQ może zaburzyć sekwencję, chyba że platforma celowo zachowuje kolejność. Ponawianie prób w pamięci w ramach jednego odbiorcy naturalnie utrzymuje kolejność wiadomości tego odbiorcy, chociaż wielu odbiorców nadal przetwarza je równolegle. Niektóre systemy wykorzystują numery sekwencyjne lub kolejność na poziomie aplikacji do rekonstrukcji prawidłowej sekwencji po każdym mechanizmie ponawiania prób.
Jakie względy bezpieczeństwa dotyczą kolejek martwych listów?
Kolejki DLQ zawierają te same wrażliwe dane, co kolejki główne, a czasami nawet więcej, ponieważ uwzględniają kontekst awarii. Należy stosować identyczne szyfrowanie, kontrolę dostępu i rejestrowanie audytu. Należy zachować ostrożność przy stosowaniu mechanizmów odtwarzania, ponieważ ponowne przetwarzanie starych wiadomości może wywołać nieoczekiwane skutki uboczne, jeśli systemy niższego rzędu nie są idempotentne. Niektóre branże podlegające regulacjom wymagają jawnych przepływów pracy zatwierdzania przed uzyskaniem dostępu do wiadomości DLQ lub ich odtworzeniem.
Kiedy należy całkowicie unikać ponawiania prób w pamięci?
Pomiń je, gdy przetwarzanie ma skutki uboczne, które nie są idempotentne, np. dwukrotne obciążenie karty kredytowej z powodu ponownych prób jest katastrofalne w skutkach. Unikaj ich, gdy ważna jest semantyka jednokrotna, a brakuje deduplikacji. Nie polegaj na nich w przypadku długotrwałych operacji, w których proces może nie przetrwać wystarczająco długo, aby wykonać ponownych prób. Nie używaj ich również, gdy zespoły operacyjne potrzebują wglądu w schematy awarii bez wdrażania zmian w kodzie.
Jak przedstawiają się koszty w skali przedsiębiorstwa?
Typowa konfiguracja AWS ze standardowymi kolejkami SQS i DLQ może kosztować kilka dolarów za milion wiadomości, plus miejsce na przechowywanie wiadomości. W przypadku systemu przetwarzającego miliardy miesięcznie, staje się to istotne. Ponawianie prób w pamięci przenosi koszty na moc obliczeniową, za którą już płacisz. Jednak nawał ponownych prób może gwałtownie zwiększyć obciążenie procesora i pamięci, potencjalnie wymagając większych instancji. Większość analiz całkowitego kosztu posiadania (TCP) preferuje rozwiązania w pamięci w przypadku zadań o niskiej krytyczności i dużej objętości, a DLQ w przypadku niezbędnych przepływów pracy o mniejszej objętości.

Wynik

Wybierz kolejki martwych komunikatów, gdy utrata wiadomości jest niedopuszczalna, a zespoły operacyjne potrzebują jasnych granic zarządzania awariami. Wybierz ponawianie prób w pamięci, gdy najważniejsza jest szybkość, ceniona jest prostota infrastruktury, a awarie mają charakter przejściowy, a nie systemowy. Wiele dojrzałych systemów łączy oba te aspekty, wykorzystując ponawianie prób w pamięci do natychmiastowego odzyskiwania i DLQ jako najlepsze zabezpieczenie.

Powiązane porównania

Agregacja danych telemetrycznych a rejestrowanie z jednego źródła

Agregacja danych telemetrycznych konsoliduje metryki, logi i ślady z wielu źródeł w ujednolicony kanał, podczas gdy logowanie z jednego źródła koncentruje się na przechwytywaniu i analizowaniu danych z jednego konkretnego źródła. Właściwy wybór zależy od złożoności systemu, celów w zakresie obserwowalności oraz skali operacyjnej.

AWS kontra Google Cloud

Porównanie analizuje Amazon Web Services i Google Cloud, badając ich ofertę usług, modele cenowe, globalną infrastrukturę, wydajność, doświadczenie deweloperów oraz optymalne przypadki użycia, pomagając organizacjom wybrać platformę chmurową najlepiej dopasowaną do ich wymagań technicznych i biznesowych.

Bazy danych wektorowe a tradycyjne bazy danych relacyjne

Bazy danych wektorowe specjalizują się w przechowywaniu i wyszukiwaniu wielowymiarowych osadzeń na potrzeby zadań związanych ze sztuczną inteligencją i podobieństwem, podczas gdy tradycyjne relacyjne bazy danych doskonale radzą sobie ze strukturalnymi danymi, precyzyjnymi zapytaniami i transakcjami ACID. Wybór między nimi zależy od tego, czy Twoje obciążenie koncentruje się na wyszukiwaniu semantycznym, czy na integralności transakcyjnej.

Buforowanie lokalne a scentralizowane klastry buforowania

Lokalna pamięć podręczna przechowuje dane bezpośrednio na serwerach aplikacji, co zapewnia dostęp z bardzo niskim opóźnieniem, podczas gdy scentralizowane klastry pamięci podręcznej wdrażają dedykowaną, współdzieloną infrastrukturę, do której wiele usług może uzyskiwać dostęp jednocześnie, co pozwala na spójne zarządzanie stanem.

Debugowanie systemów rozproszonych a debugowanie systemów lokalnych

Debugowanie systemów rozproszonych rozwiązuje problemy w wielu maszynach i usługach sieciowych, podczas gdy debugowanie systemów lokalnych koncentruje się na problemach w obrębie jednej maszyny lub aplikacji. Każde podejście wymaga innych narzędzi, modeli mentalnych i strategii, aby skutecznie izolować i rozwiązywać problemy.