Robocikowo>ROBOCIKOWO
Infrastruktura

AWS SQS — co to jest i jak działa?

aws-sqs-co-to-jest-i-jak-dziala-cover

Amazon Simple Queue Service (SQS) to w pełni zarządzana usługa kolejkowania wiadomości w chmurze AWS, pozwalająca odizolować od siebie komponenty systemu i komunikować się asynchronicznie. Zrozumienie SQS jest kluczowe dla każdego, kto projektuje skalowalne, odporne na awarie aplikacje oparte na mikroserwisach lub architekturze bezserwerowej.

Czym jest AWS SQS?

AWS SQS (Amazon Simple Queue Service) to zarządzana usługa kolejkowania wiadomości udostępniana przez Amazon Web Services: dywizja chmurowa Amazon.com — największy dostawca usług chmurowych na świecie, oferujący ponad 200 usług infrastrukturalnych, platformowych i aplikacyjnych. Jej zadaniem jest bezpieczne odbieranie, przechowywanie i dostarczanie komunikatów pomiędzy niezależnymi komponentami oprogramowania. Amazon uruchomił usługę w 2006 roku — jako pierwszą publicznie dostępną ofertę w całym portfolio AWS, jeszcze przed EC2 i S3.

SQS nie jest bazą danych ani brokerem strumieniowania zdarzeń na wzór Apache Kafka. To klasyczna kolejka komunikatów — wirtualny bufor, który przechowuje zadania i dane, dopóki docelowy komponent nie będzie gotowy je odebrać. W odróżnieniu od komunikacji synchronicznej (np. bezpośrednich wywołań HTTP REST), SQS wprowadza paradygmat asynchroniczny: nadawca wiadomości i jej odbiorca mogą działać niezależnie, w różnym tempie i nie muszą być dostępni jednocześnie.

Usługa jest w pełni zarządzana — AWS zajmuje się infrastrukturą, skalowaniem, replikacją i aktualizacjami. Użytkownik płaci wyłącznie za faktyczne użycie (model pay-as-you-go) i nie konfiguruje serwerów, brokerów ani klastrów.

Jak to działa?

Każda wiadomość w SQS przechodzi przez skończony zestaw stanów. Zrozumienie tych stanów — i warunków przejść między nimi — jest kluczem do poprawnego projektowania producentów i konsumentów oraz do zrozumienia, dlaczego Visibility Timeout: czas, przez który pobrana wiadomość jest ukryta przed innymi konsumentami — daje konsumentowi okno na przetworzenie i potwierdzenie bez ryzyka podwójnego odbioru, DLQ: Dead-Letter Queue — kolejka przechowująca wiadomości, których nie udało się przetworzyć po określonej liczbie prób; służy do analizy błędów i ponownego przetworzenia i idempotencja: właściwość operacji, której wielokrotne wykonanie z tymi samymi danymi wejściowymi daje identyczny wynik bez skutków ubocznych są niezbędne, a nie opcjonalne.

Model pull — własne workery

Kiedy konsumentem jest własny worker (instancja EC2, kontener ECS, serwis Kubernetes), przetwarzanie wygląda następująco:

  1. Wysyłanie. Producent wysyła wiadomość do URL kolejki. Maksymalny rozmiar to 256 KB; dla większych ładunków wzorzec z S3 (S3 reference pattern): sposób obsługi ładunków większych niż 256 KB: właściwe dane zapisuje się do Amazon S3, a wiadomość SQS zawiera tylko referencję (URI) do obiektu w S3. Konsument pobiera ładunek z S3 po odczytaniu referencji. Bibliotekę Extended Client Library (m.in. dla Javy) automatyzuje ten proces.. Opcjonalny parametr DelaySeconds (0–900 s) powoduje, że wiadomość pozostaje niewidoczna przez zdefiniowany czas zanim trafi do puli dostępnych — przydatne gdy konsument potrzebuje chwili na gotowość lub gdy chcemy rozłożyć obciążenie w czasie. Do jednej kolejki może wysyłać wielu producentów.
  2. Replikacja. SQS natychmiast replikuje odebraną wiadomość na wiele serwerów w różnych Availability Zones: izolowane lokalizacje w obrębie jednego regionu AWS, posiadające własne zasilanie, chłodzenie i łączność sieciową — awaria jednej strefy nie wpływa na pozostałe. API zwraca potwierdzenie dopiero po zakończeniu replikacji — wiadomość jest trwała od momentu odpowiedzi.
  3. Pobieranie (polling). Konsument wywołuje ReceiveMessage — dostępne są dwa tryby:
    • Short polling (WaitTimeSeconds=0): SQS odpowiada natychmiast, sprawdzając tylko część maszyn przechowujących dane kolejki. Jeśli wiadomości akurat są na niesprawdzonych maszynach — odpowiedź wraca pusta, mimo że kolejka nie jest pusta (false empty).
    • Long polling (WaitTimeSeconds 1–20 s): zapytanie pozostaje otwarte — SQS przeszukuje wszystkie serwery przez cały zadeklarowany czas i odpowiada natychmiast po znalezieniu wiadomości. Eliminuje false empty. Zalecany dla każdego workera; przez trigger Lambda konfigurowany automatycznie.
    • Batch odbioru: parametr MaxNumberOfMessages (maks. 10) pozwala pobrać kilka wiadomości naraz w jednym wywołaniu API — zamiast dziesięciu osobnych round-tripów, co obniża koszty i latencję.
  4. Blokada (Visibility Timeout). Odebrana wiadomość jest ukryta przed innymi konsumentami przez czas Visibility Timeout (domyślnie 30 s, maksymalnie 12 h). Jeśli przetwarzanie trwa dłużej niż limit, konsument powinien wywołać ChangeMessageVisibility aby dynamicznie przedłużyć blokadę. Jeśli tego nie zrobi, a timeout wygaśnie — SQS uzna wiadomość za nieprzetworzoną i udostępni ją ponownie, nawet gdy konsument wciąż nad nią pracuje. To jest najczęstszy powód nieintencjonalnego podwójnego przetwarzania.
  5. Potwierdzenie. Po pomyślnym przetworzeniu konsument wywołuje DeleteMessage — wiadomość jest trwale usuwana. Brak wywołania (np. wskutek wyjątku lub awarii) oznacza że po wygaśnięciu Visibility Timeout wiadomość wróci do kolejki. W kolejkach Standard at-least-once delivery oznacza, że w rzadkich przypadkach ta sama wiadomość może trafić do dwóch konsumentów jednocześnie — nawet bez awarii. Dlatego logika konsumenta musi być idempotentna.

Model trigger — Lambda i Event Source Mapping

Gdy SQS triggeruje AWS Lambda: bezserwerowa usługa obliczeniowa AWS — kod wykonywany na żądanie, bez zarządzania serwerami, rozliczany za czas wykonania przez Event Source Mapping: mechanizm AWS łączący źródło zdarzeń (np. SQS) z funkcją Lambda — AWS zarządza pollingiem, batchingiem i potwierdzaniem wiadomości zamiast programisty, model jest fundamentalnie inny.

AWS Lambda Service (nie programista) odpytuje kolejkę w trybie long polling: odpytywanie z oczekiwaniem — zapytanie ReceiveMessage pozostaje otwarte do 20 sekund, a SQS przeszukuje wszystkie serwery i odpowiada natychmiast po znalezieniu wiadomości. Eliminuje fałszywe puste odpowiedzi i obniża liczbę płatnych żądań API., batching: łączenie wielu wiadomości (do 10) w jedno wywołanie funkcji Lambda zamiast osobnego wywołania na każdą wiadomość — zmniejsza liczbę żądań API i koszty oraz zwiększa przepustowość. i wywołuje funkcję Lambda. Jeśli funkcja wykona się pomyślnie — AWS automatycznie wywołuje DeleteMessage dla wszystkich wiadomości w batchu. Programista nie pisze kodu do pollingu ani do potwierdzania wiadomości.

Kluczowa różnica przy błędzie: w modelu pull konsument może potwierdzić część wiadomości z batcha. W ESM domyślnie cały batch wraca do kolejki gdy Lambda rzuci wyjątek. Aby potwierdzać wiadomości granularnie, należy skonfigurować ReportBatchItemFailures — wtedy Lambda zwraca listę nieudanych messageId i tylko one wracają do kolejki.

Ścieżka błędu — retry, DLQ i wygaśnięcie

Gdy konsument nie potwierdzi przetworzenia — niezależnie od modelu — wiadomość wchodzi w cykl ponownych prób:

Retry. Po wygaśnięciu Visibility Timeout wiadomość wraca do stanu widoczna i jest dostępna dla kolejnego konsumenta. Licznik ApproximateReceiveCount rośnie przy każdym pobraniu.

Dead-Letter Queue. Gdy ApproximateReceiveCount osiągnie wartość maxReceiveCount skonfigurowaną w polityce redrive, SQS automatycznie przenosi wiadomość do DLQ. Wiadomość jest tam dostępna do analizy i ewentualnego ponownego przetworzenia (redrive) po naprawieniu błędu.

Wygaśnięcie. Każda wiadomość — zarówno w kolejce głównej, jak i w DLQ — ma własny MessageRetentionPeriod (od 1 minuty do 14 dni, domyślnie 4 dni). Po upływie tego czasu SQS usuwa wiadomość bezpowrotnie i bez ostrzeżenia. To trzecia ścieżka wyjścia obok sukcesu i DLQ. Metryka ApproximateAgeOfOldestMessage w CloudWatch pozwala wykryć wiadomości zbliżające się do wygaśnięcia.

Z jakich elementów się składa?

Kolejki Standard

Domyślny typ, przeznaczony do zastosowań wymagających bardzo wysokiej przepustowości. Obsługują praktycznie nieograniczoną liczbę transakcji na sekundę. Wadą jest gwarancja dostarczenia „co najmniej raz" (at-least-once): przy dużej skali zdarza się, że ta sama wiadomość trafi do konsumenta więcej niż raz. Kolejność dostarczania jest przybliżona (best-effort). Wymaga to, aby kod konsumenta był idempotentny: właściwość operacji, której wielokrotne wykonanie z tymi samymi parametrami daje identyczny wynik — bez skutków ubocznych — wielokrotne wykonanie tej samej operacji nie może powodować skutków ubocznych.

Kolejki Standard obsługują wzorzec competing consumers: wzorzec, w którym wiele instancji konsumenta rywalizuje o wiadomości z jednej kolejki — każda wiadomość trafia do dokładnie jednego z nich. Pozwala skalować przetwarzanie przez dodawanie kolejnych workerów.: wielu producentów może wysyłać do tej samej kolejki, a wielu konsumentów może ją równocześnie odpytywać — ale każda wiadomość trafia do dokładnie jednego konsumenta. To nie jest broadcasting. Jeśli ta sama wiadomość ma trafić do kilku niezależnych odbiorców jednocześnie, konieczny jest wzorzec Fan-Out: wzorzec rozgłaszania jednej wiadomości do wielu odbiorców jednocześnie. W AWS realizowany przez SNS publikujący zdarzenie do wielu subskrybujących kolejek SQS, z których każda ma własnego konsumenta.: SNS publikuje wiadomość do wielu kolejek SQS naraz, a każda kolejka obsługuje własnego konsumenta.

Kolejki FIFO

Kolejki FIFO gwarantują ścisłą kolejność przetwarzania i deduplikację wiadomości. AWS opisuje ten mechanizm jako „exactly-once processing": wiadomość o tym samym Message Deduplication ID nie zostanie dostarczona konsumentowi więcej niż raz w ciągu 5-minutowego okna deduplikacji. Ważne zastrzeżenie: gwarancja dotyczy dostarczenia przez SQS, nie wykonania logiki biznesowej — jeśli konsument pobierze wiadomość, przetworzy ją, lecz nie wywoła DeleteMessage przed wygaśnięciem Visibility Timeout (np. z powodu awarii), wiadomość wróci do kolejki i zostanie dostarczona ponownie. Przepustowość FIFO jest ograniczona: 300 wiadomości/s w trybie standardowym, do 3 000 z batchingiem i do 70 000 TPS w trybie High Throughput FIFO. Koszt operacyjny jest nieco wyższy niż dla kolejek Standard.

Dead-Letter Queue (DLQ)

Wydzielona kolejka, do której wiadomości trafiają automatycznie po przekroczeniu zdefiniowanej liczby nieudanych prób przetwarzania (maxReceiveCount). Zapobiega tzw. poison pill — sytuacji, gdy błędna wiadomość blokuje kolejkę w nieskończonej pętli. Po naprawieniu błędu możliwe jest „redrive" — przesłanie wiadomości z DLQ z powrotem do kolejki źródłowej.

Visibility Timeout i parametry czasu

Najważniejsze parametry czasowe kolejki:

  • Visibility Timeout — czas blokady wiadomości po odebraniu (domyślnie 30 s, maks. 12 h).
  • Message Retention Period — jak długo nieprzetworzona wiadomość zostaje w kolejce: od 1 minuty do 14 dni, domyślnie 4 dni.
  • Delay Seconds — opóźnienie, po którym wysłana wiadomość staje się widoczna (0–900 s).

Dla długotrwałych zadań konieczne jest cykliczne odświeżanie czasu widoczności przez wywołanie ChangeMessageVisibility.

Atrybuty wiadomości (Message Attributes)

Do każdej wiadomości można dołączyć do 10 Message Attributes: metadane dołączone do wiadomości SQS — pary klucz-wartość z typem (String, Number, Binary), dostępne dla konsumenta przed deserializacją treści — par klucz-wartość z typem (String, Number, Binary). Atrybuty są dostępne dla konsumenta bez deserializacji treści payloadu, co pozwala na wczesną decyzję o przetwarzaniu lub odrzuceniu zadania.

Typowe zastosowania atrybutów:

  • Priorytet zadaniapriority="high"
  • Identyfikator klienta (architektura multi-tenant) — tenant_id
  • Format payloaducontent_type="application/json"
  • Język dokumentulanguage="pl"
  • Serwis źródłowysource="checkout-service"

Przechowywanie tych danych w atrybutach — zamiast w treści wiadomości — upraszcza logikę workera i pozwala filtrować zadania bez parsowania JSON.

CechaSQS StandardSQS FIFO
Gwarancja dostarczeniaCo najmniej razDokładnie raz
Zachowanie kolejnościPrzybliżone (best-effort)Ścisła i gwarantowana
PrzepustowośćNiemal nieograniczona300–70 000 TPS
DuplikatyMożliwe (wymaga idempotencji)Wbudowana deduplikacja
ZastosowaniaLogi, przetwarzanie multimediów, e-learningTransakcje finansowe, e-commerce, logistyka
Porównanie typów kolejek

Operacje wsadowe

SQS pozwala grupować wiele wiadomości w jedno wywołanie API, co znacząco obniża koszty i poprawia przepustowość. Opłaty naliczane są za żądanie, a nie za wiadomość — 10 wiadomości wysłanych w jednym batchu kosztuje tyle samo co 1 wywołanie, nie 10.

SendMessageBatch — wysyła do 10 wiadomości w jednym żądaniu. Każda wiadomość w batchu może mieć odrębny payload, atrybuty, DelaySeconds i MessageGroupId (FIFO). Łączny rozmiar batcha nie może przekraczać 256 KB.

DeleteMessageBatch — usuwa do 10 wiadomości (potwierdza przetworzenie) w jednym żądaniu. Zalecane zamiast sekwencji pojedynczych wywołań DeleteMessage — szczególnie gdy worker przetwarza wiadomości w pętli.

ReceiveMessage z parametrem MaxNumberOfMessages=10 — zwraca do 10 wiadomości jednocześnie w jednej odpowiedzi. Kombinacja: poll po 10, przetwórz równolegle, skasuj batch — to wzorzec o najniższym koszcie API na wiadomość.

Do czego może być używane?

Rozprzężenie mikroserwisów (Decoupling). Gdy serwis A wywołuje serwis B bezpośrednio przez HTTP, awaria B natychmiast blokuje A. Zastąpienie bezpośredniego wywołania kolejką SQS sprawia, że serwis A zapisuje zadanie do kolejki i nie musi czekać. Serwis B przetwarza je w swoim tempie. Awaria B nie powoduje utraty danych ani błędów po stronie A.

Buforowanie szczytów ruchu. SQS sprawdza się jako bufor absorbujący nagłe wzrosty obciążenia. Klasyczny przykład: platforma e-learningowa podczas ogólnopolskich egzaminów. Tysiące odpowiedzi spływają w ciągu sekund — baza danych nie jest w stanie ich obsłużyć bezpośrednio. SQS przyjmuje wszystkie odpowiedzi natychmiast, a serwery przetwarzają je z kontrolowaną szybkością.

Przetwarzanie w tle i batch processing. Serwisy do hostingu wideo (np. transkodowanie plików 4K) czy kampanie mailingowe w systemach CRM — zadania są odkładane do kolejki, a flota workerów przetwarza je asynchronicznie.

Wzorzec Fan-Out z Amazon SNS. SQS najczęściej stosuje się razem z Amazon SNS (Simple Notification Service). Jeden event (np. dokonana płatność) publikowany do SNS jest jednocześnie przekazywany do wielu niezależnych kolejek SQS — do serwisu fakturowego, SMS-owego i logistycznego. Każdy serwis otrzymuje własną kopię zdarzenia i przetwarza je niezależnie.

Integracja z AWS Lambda. Dzięki Event Source Mapping (ESM) Lambda automatycznie pobiera i przetwarza wiadomości z kolejki — bez ręcznego implementowania pollingu. AWS zarządza skalowaniem równoległości na podstawie głębokości kolejki.

SQS w erze AI

Rosnąca popularność dużych modeli językowych i systemów agentowych sprawia, że SQS zyskuje nową rolę — nie tylko jako klej między mikroserwisami, ale jako element infrastruktury, który pozwala kontrolować tempo, koszty i niezawodność przepływów opartych na AI.

Kolejkowanie żądań do modeli językowych

Publiczne API modeli językowych (OpenAI, Anthropic, Google) egzekwują rate limiting: mechanizm ograniczający liczbę żądań API w jednostce czasu — np. 60 req/min lub określony limit tokenów na minutę: konkretna liczba wywołań na minutę i pula tokenów. Aplikacje obsługujące wielu użytkowników jednocześnie szybko wyczerpują te limity, jeśli wywołania trafiają do LLM bezpośrednio.

SQS rozwiązuje ten problem klasycznie: każde żądanie użytkownika trafia do kolejki, a dedykowana pula workerów odczytuje je w tempie dostosowanym do limitów API. Worker, który dostanie odpowiedź 429 (Too Many Requests), nie gubi żądania — cofa je do kolejki i próbuje ponownie po odczekaniu. DLQ wychwytuje żądania, które permanentnie nie mogą być przetworzone (np. błędne dane wejściowe). Takie podejście stosują m.in. systemy obsługujące tysiące zapytań dziennie do modeli takich jak GPT czy Claude, gdzie bez kolejkowania koszty i awarie byłyby trudne do kontrolowania.

Pipeline'y ingestion dla RAG

Systemy RAG: Retrieval-Augmented Generation — architektura łącząca model językowy z zewnętrzną bazą wiedzy przeszukiwaną w czasie rzeczywistym (Retrieval-Augmented Generation) wymagają przetworzenia dokumentów przed ich udostępnieniem modelowi: pliki muszą być podzielone na fragmenty (chunking), przetworzone przez model embeddingów i zapisane do wektorowej bazy danych. To zadanie obliczeniowo ciężkie — przetworzenie jednego PDF-a może zająć kilka sekund.

Bez kolejkowania upload dokumentu i jego przetworzenie musiałyby odbyć się synchronicznie, blokując odpowiedź użytkownikowi. Wzorzec z SQS wygląda inaczej: użytkownik przesyła plik, serwer zapisuje go do S3 i odkłada zadanie do kolejki SQS, po czym natychmiast odpowiada potwierdzeniem. Niezależna flota workerów odbiera zadania z kolejki, przetwarza dokumenty i zapisuje embeddingi do bazy wektorowej. Awaria jednego workera nie niszczy żądania — trafia ono z powrotem do kolejki po wygaśnięciu Visibility Timeout.

Komunikacja w systemach wieloagentowych

Architektury wieloagentowe — gdzie jeden agent orkiestruje pracę kilku agentów specjalistycznych — naturalnie pasują do modelu kolejkowego. Agent orkiestrator rozkłada zadanie na podzadania i publikuje każde z nich do odpowiedniej kolejki. Agenci specjalistyczni (np. agent do wyszukiwania informacji, agent do generowania kodu, agent do weryfikacji) odbierają swoje zadania niezależnie.

Kolejki FIFO gwarantują tu kolejność przetwarzania w ramach jednego wątku zadania (Message Group ID powiązany z identyfikatorem sesji). DLQ wychwytuje agentów, którzy utknęli w pętli lub zwrócili błąd. Takie podejście pozwala skalować każdy typ agenta niezależnie — jeśli agent wyszukujący jest wąskim gardłem, można uruchomić więcej jego instancji bez ingerencji w resztę systemu.

Asynchroniczny inference i zarządzanie kosztami

Nie każde wywołanie LLM musi być synchroniczne. Generowanie raportów, podsumowań dokumentów, transkrypcji wideo czy analiz sentymentu może odbywać się w tle — użytkownik prosi o wynik i dostaje powiadomienie, gdy jest gotowy. SQS jest naturalnym buforem dla takich zadań.

Dodatkowa korzyść to kontrola kosztów: zamiast skalować liczbę równoległych wywołań modelu proporcjonalnie do ruchu (co przekłada się na ogromne rachunki), kolejka pozwala ustawić sztywny sufit przepustowości (np. maksymalnie 20 równoległych workerów wywołujących LLM). W efekcie koszty inference są przewidywalne niezależnie od skoków ruchu — bufor kolejki pochłania nadmiar, a system przetwarza zadania ze stałą prędkością.

Kiedy nie używać SQS?

SQS jest celowo prostym narzędziem — ta prostota jest jego zaletą, ale też granicą. Kilka sygnałów, że potrzebujesz innego rozwiązania:

Potrzebujesz event sourcingu lub replay. SQS usuwa wiadomość po potwierdzeniu — nie można cofnąć się do wcześniejszego stanu kolejki. Jeśli chcesz wielokrotnie odtworzyć strumień zdarzeń (np. przebudować widok), wybierz Apache Kafka lub Amazon Kinesis Data Streams, które przechowują zdarzenia przez konfigurowalny czas retencji.

Musisz kierować wiadomości w różne miejsca w zależności od ich treści. Kolejka SQS nie zagląda do środka wiadomości — każdy konsument sam musi ją odebrać i sprawdzić, czy go dotyczy. Jeśli chcesz, aby zamówienia z Niemiec trafiały do innego workera niż zamówienia z USA (na podstawie pola w wiadomości), potrzebujesz warstwy, która czyta zawartość i wybiera adresata. Taką rolę pełni Amazon EventBridge — opisujemy ten wzorzec w dalszej części.

Masz nieprzerwany strumień zdarzeń, który wielu odbiorców chce analizować na bieżąco. SQS sprawdza się, gdy każda wiadomość to zadanie do wykonania raz przez jednego workera. Nie nadaje się natomiast, gdy dane napływają ciągłym potokiem (kliknięcia użytkowników, odczyty z czujników, logi) i kilka systemów jednocześnie chce je czytać, przewijać do dowolnego momentu w przeszłości i przetwarzać w oknach czasowych — na przykład na potrzeby analityki na żywo czy zasilania modeli ML. Do takich zastosowań lepiej pasuje Amazon Kinesis lub Apache Kafka, które przechowują zdarzenia i pozwalają odczytywać ten sam strumień wielokrotnie.

Potrzebujesz rozbudowanych reguł rozdzielania wiadomości między kolejki. SQS oferuje prosty model: wiadomość wpada do jednej kolejki i tam czeka na odbiorcę. Nie ma wbudowanego mechanizmu, który na podstawie etykiety wiadomości rozsyłałby ją do wielu kolejek naraz, dopasowywał odbiorców według wzorca nazwy czy automatycznie przekierowywał nieudane wiadomości według własnych reguł. Jeśli takie zaawansowane sterowanie przepływem jest sednem Twojego systemu, dojrzalszym narzędziem jest RabbitMQ — broker komunikatów, który daje pełną kontrolę nad topologią kolejek.

Zależy Ci na opóźnieniach poniżej milisekundy. Przesłanie wiadomości przez SQS i odebranie jej z powrotem zajmuje zwykle kilkadziesiąt milisekund — to cena za to, że kolejka działa w chmurze, jako osobna usługa dostępna przez sieć. Dla większości systemów jest to niezauważalne, ale jeśli dwa komponenty muszą wymieniać się danymi w czasie liczonym w ułamkach milisekundy (np. w handlu wysokich częstotliwości czy przetwarzaniu sygnału w czasie rzeczywistym), pośrednik w chmurze jest zbyt wolny. W takich przypadkach sięga się po rozwiązania działające w pamięci tej samej maszyny (np. Redis) albo po bezpośrednie połączenie między serwisami, z pominięciem kolejki.

Czym różni się od innych rozwiązań?

SQS vs Apache Kafka

Kafka to rozproszony log zdarzeń (event streaming), a nie klasyczna kolejka. Kafka przechowuje wiadomości przez konfigurowalny czas retencji (np. 7 dni lub bezterminowo) i pozwala na wielokrotne odczytywanie tych samych zdarzeń przez różnych konsumentów. SQS usuwa wiadomość po potwierdzeniu przetworzenia. Kafka wymaga zarządzania własnym klastrem i operacji DevOps. SQS jest w pełni zarządzany. Kafka nadaje się do strumieniowania danych w czasie rzeczywistym i analizy logów. SQS nadaje się do task queues i komunikacji asynchronicznej między serwisami.

SQS vs RabbitMQ

RabbitMQ to klasyczny broker komunikatów z zaawansowanym routingiem opartym na protokole AMQP: AMQP (Advanced Message Queuing Protocol) to otwarty standard komunikacji między aplikacjami a brokerami komunikatów. Definiuje format wiadomości i reguły ich wymiany, dzięki czemu różne systemy (niezależnie od języka i dostawcy) mogą współpracować przez tego samego brokera, np. RabbitMQ.. Sprawdza się jako lokalny broker w sieciach prywatnych i środowiskach z restrykcyjnymi wymaganiami bezpieczeństwa. Nie skaluje się tak łatwo globalnie jak SQS. W modelu SaaS lub cloud-native SQS jest prostszy w utrzymaniu i integracji z resztą ekosystemu AWS.

SQS vs Google Cloud Pub/Sub

Oba serwisy to zarządzane kolejki w chmurze publicznej z podobnym modelem dostarczania i płatnością za żądania. Najważniejsza techniczna różnica: Google Cloud Pub/Sub obsługuje zarówno tryb pull (jak SQS, konsument sam odpytuje), jak i tryb push — broker wywołuje endpoint HTTP konsumenta bezpośrednio, co eliminuje potrzebę pollingu po stronie aplikacji.

Pub/Sub oferuje też natywną replikację globalną i nie jest związany z regionem, podczas gdy SQS działa w obrębie jednego regionu AWS. Semantyka dostarczania jest analogiczna: at-least-once dla kolejek standardowych, ordered delivery dla wariantów z gwarancją kolejności (FIFO w SQS, klucze kolejności w Pub/Sub). Oba rozwiązania są w pełni zarządzane i nie wymagają utrzymywania własnej infrastruktury brokerskiej.

Decydująca różnica to jednak ekosystem i integracje: Pub/Sub łączy się natywnie z usługami Google Cloud (BigQuery, Dataflow, Cloud Functions), SQS — z ekosystemem AWS (Lambda, SNS, EventBridge, S3). Wybór między nimi sprowadza się do dostawcy chmury, nie do możliwości technicznych.

SQS i Amazon EventBridge

Amazon EventBridge: zarządzana usługa event-bus w ekosystemie AWS — kieruje zdarzenia do różnych celów (SQS, Lambda, SNS, API Gateway) na podstawie reguł filtrowania opartych na treści zdarzeń to zarządzana szyna zdarzeń (event bus) w ekosystemie AWS. W przeciwieństwie do SNS (push, fanout) EventBridge oferuje content-based routing: reguły filtrują zdarzenia według ich struktury i kierują je do różnych celów (SQS, Lambda, SNS, Step Functions, API Gateway).

Wzorzec: EventBridge jako inteligentny router + SQS jako bufor dla każdego konsumenta. Przykład: zdarzenie order.placed publikowane przez serwis zamówień trafia do EventBridge, który na podstawie pola country kieruje je do kolejki SQS dla Europy lub kolejki SQS dla USA — każda z własną flotą workerów. Takie podejście łączy elastyczność routingu (EventBridge) z niezawodnością buforowania i asynchronicznego przetwarzania (SQS).

EventBridge natywnie integruje się z dziesiątkami źródeł SaaS (Salesforce, Zendesk, GitHub) i usług AWS — każde zdarzenie może bez kodu trafić do kolejki SQS. To czyni go preferowaną alternatywą dla SNS w architekturach, gdzie routing nie jest trywialny.

Monitoring i CloudWatch

Amazon SQS eksportuje metryki do Amazon CloudWatch automatycznie, bez konfiguracji. Obserwacja stanu kolejek jest kluczowa — zatrzymanie workerów lub błędna konfiguracja może prowadzić do przepełnienia kolejki i utraty wiadomości po upływie okresu retencji.

Kluczowe metryki

ApproximateNumberOfMessagesVisible — liczba wiadomości gotowych do odbioru. Gwałtowny wzrost oznacza, że workery nie wyrabiają z przetwarzaniem lub całkowicie się zatrzymały. Podstawowy alarm produkcyjny.

ApproximateAgeOfOldestMessage — wiek najstarszej wiadomości w sekundach. To najważniejsza metryka do monitorowania SLA: jeśli wiadomość czeka zbyt długo, system nie dotrzymuje wymagań czasowych. Ustaw alarm, gdy wartość przekroczy akceptowalny próg.

ApproximateNumberOfMessagesNotVisible — wiadomości aktualnie przetwarzane przez konsumentów (in-flight, ukryte z powodu Visibility Timeout). Wysoka wartość przy braku wzrostu Visible sugeruje wolne przetwarzanie lub zbyt długi Visibility Timeout.

NumberOfMessagesSent / Received / Deleted — throughput kolejki. Stosunek wysłanych do usuniętych pozwala wykryć backlog narastający w czasie.

NumberOfEmptyReceives — ile razy poll zwrócił pustą odpowiedź. Jeśli wartość jest wysoka, kolejka jest często pusta — to sygnał do włączenia long polling (WaitTimeSeconds=20), który eliminuje kosztowne puste żądania.

Alerty produkcyjne (minimum)

  • ApproximateAgeOfOldestMessage > próg × 2 → alarm CRITICAL (workery zatrzymane lub zbyt wolne)
  • ApproximateNumberOfMessagesVisible dla DLQ > 0 → alarm WARNING (pojawiły się trwałe błędy)
  • ApproximateNumberOfMessagesVisible gwałtownie rośnie → alarm WARNING (narastający backlog)

Najczęstsze problemy i pułapki

Zbyt krótki Visibility Timeout — podwójne przetwarzanie

Najczęstszy błąd operacyjny. Przykład: worker pobiera wiadomość i potrzebuje 45 sekund na przetworzenie, ale Visibility Timeout wynosi 30 sekund. Po 30 sekundach SQS uznaje, że wiadomość nie została przetworzona i udostępnia ją ponownie — drugi worker odbiera tę samą wiadomość i zaczyna od nowa. W efekcie ta sama operacja wykonuje się równolegle dwa razy, co może prowadzić do zduplikowanych rekordów w bazie danych, podwójnych transakcji finansowych lub wysłania dwóch maili.

Rozwiązanie: ustaw Visibility Timeout na 2–3× dłuższy niż typowy czas przetwarzania. Dla zadań o zmiennym czasie trwania wywołuj ChangeMessageVisibility w trakcie przetwarzania, aby dynamicznie przedłużać blokadę.

Pełna DLQ — ciche znikanie wiadomości

DLQ ma własny okres retencji (domyślnie 4 dni). Jeśli DLQ jest pełna lub wiadomości nie są z niej konsumowane, po upływie retencji przepadają bezpowrotnie. Wiele zespołów konfiguruje DLQ jako "sieć bezpieczeństwa" i nigdy nie sprawdza jej zawartości — błędy narastają, a wiadomości znikają.

Obowiązkowo: alarm na ApproximateNumberOfMessagesVisible > 0 w DLQ, regularne przeglądanie błędów i procedura redrive po naprawieniu przyczyny.

Błędy IAM — zbyt szerokie lub zbyt wąskie uprawnienia

Zbyt szeroka polityka SendMessage bez warunku aws:SourceAccount może pozwolić dowolnemu kontu AWS na wysyłanie wiadomości do kolejki — klasyczny wektor ataku w architekturach multi-account. Z drugiej strony zbyt wąskie uprawnienia (brak sqs:ReceiveMessage lub sqs:DeleteMessage dla roli Lambda) generują ciche błędy: Lambda nie może odebrać wiadomości lub nie może ich usunąć po przetworzeniu, co prowadzi do nieskończonej pętli prób.

Throttling Lambda przy dużym napływie wiadomości

Gdy SQS trigger Lambda jest skonfigurowany z dużą liczbą wiadomości, AWS automatycznie skaluje liczbę równoległych instancji Lambda. Jeśli zostanie osiągnięty account-level concurrency limit (domyślnie 1 000), nowe instancje są throttlowane — wiadomości zostają w kolejce, ApproximateAgeOfOldestMessage rośnie. Rozwiązanie: zarezerwuj dedykowaną pulę concurrent executions dla krytycznych funkcji (Reserved Concurrency) lub ustaw limit maksymalnej współbieżności triggera SQS.

Poison messages bez DLQ

Wiadomość z nieprawidłowym formatem JSON, referencją do nieistniejącego zasobu lub powodująca wyjątek w kodzie workera będzie pobierana i odrzucana w kółko — aż do wygaśnięcia Visibility Timeout, po którym wraca do kolejki. Bez skonfigurowanego maxReceiveCount i DLQ taka wiadomość może blokować przetwarzanie przez całe dni. Zawsze konfiguruj DLQ z maxReceiveCount = 3–5.

Dobre praktyki

Long polling — zawsze

Ustaw WaitTimeSeconds=20 we wszystkich wywołaniach ReceiveMessage. Long polling eliminuje puste odpowiedzi (SQS czeka do 20 sekund na pojawienie się wiadomości zamiast od razu zwracać pustą odpowiedź), co obniża liczbę płatnych żądań API i zmniejsza zużycie zasobów sieciowych. Dla triggera Lambda long polling jest konfigurowany automatycznie przez AWS.

Batch API — grupuj wysyłanie i potwierdzanie

Używaj SendMessageBatch i DeleteMessageBatch zamiast pojedynczych wywołań. Przy 10 wiadomościach na batch koszty API spadają 10-krotnie. Pamiętaj o limicie 256 KB łącznego rozmiaru batcha — przy dużych payloadach może to ograniczać efektywny rozmiar paczki.

DLQ z alarmem — obowiązkowo

Każda kolejka produkcyjna powinna mieć skonfigurowane: DLQ z maxReceiveCount = 3–5 oraz alarm CloudWatch na ApproximateNumberOfMessagesVisible > 0 dla DLQ. Brak DLQ oznacza, że problematyczne wiadomości będą krążyć wiecznie lub cicho znikać po wygaśnięciu retencji.

Idempotentni konsumenci — szczególnie przy SQS Standard

Zaprojektuj logikę biznesową tak, aby wielokrotne przetworzenie tej samej wiadomości nie powodowało skutków ubocznych. Techniki: deduplikacja po identyfikatorze (przechowuj ID przetworzonych wiadomości w Redis lub bazie z TTL), operacje upsert zamiast insert, wersjonowanie rekordów. Idempotencja chroni zarówno przed duplikatami z SQS Standard, jak i przed scenariuszem podwójnego przetwarzania wywołanym przez zbyt krótki Visibility Timeout.

Visibility Timeout z marginesem

Ustaw Visibility Timeout na 2–3× dłuższy niż typowy czas przetwarzania. Monitoruj ApproximateNumberOfMessagesNotVisible — jeśli wartość jest wysoka przy niskim throughput, Timeout jest za długi. Dla zadań o nieprzewidywalnym czasie trwania wywołuj ChangeMessageVisibility periodycznie w trakcie przetwarzania (np. co 80% aktualnego limitu).

Message Attributes zamiast metadanych w payloadzie

Przekazuj kontekst operacyjny (priorytet, tenant, język, typ) przez Message Attributes, nie przez JSON payload. Konsument może odczytać atrybuty bez deserializacji treści — co przyspiesza wczesne filtrowanie i upraszcza logikę.

Szyfrowanie i zasada najmniejszych uprawnień

Używaj SSE-SQS (szyfrowanie kluczem zarządzanym przez AWS) dla standardowych wymagań bezpieczeństwa. Dla środowisk wymagających audytu operacji kryptograficznych przełącz na SSE-KMS. Polityki IAM powinny być zasobowe (Resource-based Policy), z warunkiem aws:SourceAccount dla cross-account, i stosować zasadę najmniejszych uprawnień — osobne role do wysyłania i odbierania.

Dlaczego to jest istotne?

SQS rozwiązuje jeden z fundamentalnych problemów inżynierii oprogramowania: jak sprawić, by niezależne komponenty systemu mogły komunikować się niezawodnie, nie powodując kaskadowych awarii.

W architekturach monolitycznych problem jest mały — wszystko działa w jednym procesie. Gdy jednak system rośnie i staje się siecią dziesiątek lub setek mikroserwisów, bezpośrednie synchroniczne wywołania między nimi tworzą sieć kruchych zależności. Awaria jednego serwisu może zablokować cały łańcuch zależnych komponentów.

SQS rozbija tę zależność. Producent zapisuje zadanie do kolejki i znika. Konsument pobiera zadanie wtedy, gdy jest gotowy — nie szybciej, nie wolniej. Jeśli konsument padnie, zadanie wróci do kolejki. Jeśli producent generuje tysiące zdarzeń na sekundę, a konsument przetwarza tylko sto — kolejka jest buforem absorbującym różnicę.

To sprawia, że SQS jest szczególnie wartościowy w kontekście architektury bezserwerowej z AWS Lambda: pozwala skalować przetwarzanie elastycznie względem aktualnego obciążenia, bez utrzymywania stałej infrastruktury. Dla firm budujących aplikacje cloud-native na AWS jest to jeden z pierwszych serwisów, który wchodzi do architektury — nie dlatego, że jest modny, ale dlatego, że rozwiązuje realne, codzienne problemy projektowania odpornych systemów.

Źródła

Udostępnij to opracowanie