Új sorozatot indítunk az AWS üzenetkezelő szolgáltatásairól. Az üzenetkezelés ezúttal mint a mikroszervíz-alapú alkalmazások egyes komponenseinek függetlenítését (decoupling) célzó mechanizmus értendő, azaz sorozatunkban az alábbi szolgáltatásokat tárgyaljuk:
- SQS,
- SNS,
- Kinesis és
- Amazon MQ.
Az SQS (Simple Queue Service, Egyszerű [üzenet]sor-szolgáltatás) az AWS első, legrégibb szolgáltatása. Mint a fenti másik három szolgáltatás, ez is arra való, hogy üzeneteket vesz át egy (vagy több) előállító, azaz producer szoftver-összetevőtől, és átadja őket az üzeneteket feldolgozó összetevőnek, vagy összetevőknek, a consumereknek.
A komponens beépítésével két cél valósul meg:
- a producernek ne kelljen gondot viselnie a kiadott adatokra, elfelejthesse a problémát, és
- amennyiben néha sok adat jön, máskor meg kevés, akkor kevesebb erőforrást kelljen beállítani az adatok feldolgozására, mert az SQS tárolja az adatokat feldolgozásukig.
Miből áll egy üzenet?
Az SQS-be érkező üzeneteknek két része van. Maga az üzenet a body részbe kerül. Elfogad JSON-t, XML-t és formázatlan szöveget, azaz bináris adatot szöveggé alakítva küldhetünk vele. Az üzenetnek nem képezik részét, de vele együtt továbbítódnak az üzenet jellemzői, attribútumai. Az attribútumok metaadatok, amiben lényegében azt tárolunk, amit úri kedvünk kíván. Például bináris adatot is, vagy karakterláncot, vagy számot, vagy egyéni (custom) adatot. Lehet itt fontossági jelző, küldő IP, vagy bármi.
Mi kerül az üzenetbe, és mi megy az attribútumokba? Nos, a metaadatok arra valók, hogy a consumer dönthessen az üzenet kezeléséről, anélkül, hogy az üzenetet feldolgozta volna. Attribútumból egy üzenetben tíz lehet. Egy üzenet mérete legfeljebb 256 kByte, ami lehet gond - ha ennél nagyobbak az üzeneteink, akkor vagy másik szolgáltatást használunk, vagy kicsit trükközünk, vagy magát az adatot máshova tesszük, és itt linket adunk át (bár ezekkel épp az SQS lényegét nem használjuk ki).
Az üzenet útja
Az üzenet által végigjárt utat az AWS parancssori eszközében megfogalmazott kóddal szemléltetjük. Nem kellene mindenképp a kódot bemutatni, ugyanis az SQS webes felülete remekül használható üzenet elhelyezésére, kivételére, feldolgozására - mindarra, amire mi most a CLI-t használjuk. De így remélhetőleg többbet segítünk Neked. Az 121212121212 helyén a te AWS-fiókazonosítód szerepel majd.- Egy producer beteszi az üzenetet a sorba. Onnantól, hogy az üzenet a sorba került, nincs gondod a tárolásával, az AWS ugyanis a régió összes AZ-jében replikálja az üzenetedet, kis szerencsével soha nem vész el. Az AWS CLI kódból látjuk, hogy az üzenet lehet nagyon egyszerű, és azt is, hogy az SQS API-jával - mily' meglepő - egy URL használatával beszélgetünk. Az SQS válaszul elmondja, hogy a "megevett" üzenet melyik azonosítót kapta, a visszaadott ellenőrzőösszeggel pedig azt tehetjük, amit az ilyen információval szoktunk:)
Ha az emlegetett attribútumokat is használnánk, akkor a kiadandó parancs (és az SQS válasza is) kicsit hosszabb lesz:$ aws sqs send-message --queue-url https://sqs.eu-west-1.amazonaws.com/121212121212/sor --message-body "Szevasz!" { "MD5OfMessageBody": "a543601bcf9a1e177e3eb57ce9d15d78", "MessageId": "a89afa14-e03f-4e34-9136-ba0489fe0730" }
$ aws sqs send-message --queue-url https://sqs.eu-west-1.amazonaws.com/121212121212/sor --message-body "Ez borzasztóan fontos!" --message-attributes '{ "surgos":{ "DataType":"String","StringValue":"nagyon" }, "egyEsOtKozottMennyire":{ "DataType":"String","StringValue":"6"} }' { "MD5OfMessageBody": "26743c51afe27549acf70544570fc53c", "MD5OfMessageAttributes": "6e311f6a01304c33318e7dc428c31c87", "MessageId": "54896b85-fa50-476a-8aee-384716c0bb17" }
- Az üzenetek az SQS régebbi formájában, a Standard Queue-ban rendezetlenül "utaznak", azaz
- semmi nem garantálja, hogy ugyanolyan sorrendben jönnek ki, ahogy bementek (bár az AWS igyekszik megtartani a sorrendet), és
- semmi nem garantálja, hogy minden üzenet csak egyszer jön ki a csövön (nincs "exactly once delivery"). A duplák ritkák, de lesznek. Kezelésük a te dolgod.
$ aws sqs get-queue-attributes --queue-url https://sqs.eu-west-1.amazonaws.com/121212121212/sor --attribute-names All { "Attributes": { "QueueArn": "arn:aws:sqs:eu-west-1:121212121212:sor", "ApproximateNumberOfMessages": "2", ...
- A consumer elkér "egy" üzenetet a sorból feldolgozásra. Két dolgot is kiemelnénk:
- nem az üzenetet kéri, hanem egy üzenetet, semmilyen ráhatásunk nincs arra, hogy melyik üzenetet vesszük ki a sorból, és
- elkérjük (pull), és nem megkapjuk (push) az üzenetet.
$ aws sqs receive-message --queue-url https://sqs.eu-west-1.amazonaws.com/121212121212/sor { "Messages": [ { "MessageId": "a89afa14-e03f-4e34-9136-ba0489fe0730", "ReceiptHandle": "zzQf87!+(W...HaM)i", "MD5OfBody": "a543601bcf9a1e177e3eb57ce9d15d78", "Body": "Szevasz!" } ] } $ aws sqs receive-message --queue-url https://sqs.eu-west-1.amazonaws.com/121212121212/sor { "Messages": [ { "MessageId": "54896b85-fa50-476a-8aee-384716c0bb17", "ReceiptHandle": "tzU74+ee/2...)roPi", "MD5OfBody": "26743c51afe27549acf70544570fc53c", "Body": "Hú ez megváltozott! (ja nem, csak vicc volt)" } ] }
- Az üzenet ilyenkor láthatatlanná válik (azaz a következő kéréskor nem adja ide az SQS). Az ilyen üzenet angol szakkifejezéssel in-flight, azaz épp "repül". Az in-flight üzenet addig lesz láthatatlan, amíg
- az üzenetet elkérő consumer fel nem dolgozza, és a feldolgozás végével az SQS-sel törölteti az üzenetet, vagy
- eltelik az az idő (invisibility window), amit meghatároztunk a sorra nézvést. Ha egy üzenet nem törlődik, és letelik a láthatatlansági időablak, akkor ismét láthatóvá válik.
$ aws sqs receive-message --queue-url https://sqs.eu-west-1.amazonaws.com/121212121212/sor (...nincs válasz, mert minden üzenet épp láthatatlan, kivárjuk az alapértelmezés szerinti fél percet...) $ aws sqs receive-message --queue-url https://sqs.eu-west-1.amazonaws.com/121212121212/sor { "Messages": [ { "MessageId": "a89afa14-e03f-4e34-9136-ba0489fe0730", "ReceiptHandle": "zzQf87!+(W...HaM)i", "MD5OfBody": "a543601bcf9a1e177e3eb57ce9d15d78", "Body": "Szevasz!" } ] }
- Sikeres feldolgozást követően egy jól nevelt alkalmazás törölteti a feldolgozott üzenetet.
Ha pedig egy üzenetért senki nem jön el, nem várakozik örökké: alapértelmezés szerint négy nap múlva elpárolog a sorból. A négy nap legkevesebb egy percre csökkenthető, vagy legfeljebb tizennégy napra növelhető.$ aws sqs delete-message --queue-url https://sqs.eu-west-1.amazonaws.com/121212121212/sor --receipt-handle "zzQf87!+(W...HaM)i" $ aws sqs get-queue-attributes --queue-url https://sqs.eu-west-1.amazonaws.com/121212121212/sor --attribute-names ApproximateNumberOfMessages { "Attributes": { "ApproximateNumberOfMessages": "1" } }
Üzenet nem vész el
Említettük, hogy az üzenetek a sorba bekerülve több AZ-ben is replikálva vannak, fizikai vagy AWS-oldali hiba miatt nemigen veszhetnek el. A láthatalansági ablak azért jó, mert ha az üzenet elkérése után halálozik el az üzenetet feldolgozó erőforrás, akkor idővel újra megjelenik az üzenet a sorban, és majd egy másik consumer feldolgozza. Egy módon tudod elérni az üzeneteid eltűnését. Az SQS Stadard Queue a végtelenségig skálázódik, aggódnod nincs miért, biztosan lesz, aki elveszi az üzenetedet a producerektől. Ha nagyon kevés a consumer erőforrásod, akkor eltelhet az az idő, amit engedtél a sorban tölteni (és ami ugye legfeljebb tizennégy nap). Ha nem kérsz IJ-s pólót, akkor állíts be magadnak riasztást, ajánljuk figyelmedbe az ApproximateAgeOfOldestMessage
metrikát.
Miért fordul elő, hogy egy üzenet többször is megkapunk?
Nyilván nem látunk bele az SQS működésébe, de legalább két ok az AWS-től független:
- az egyik, ha tényleg kétszer tesszük be a sorba, ugyanis a producer (például hálózati hiba miatt) nem kapja meg a sorba bekerüléséről a sikert jelző üzenetet, illetve
- ha letelik a láthatatlansági időablak, pedig a feldolgozás sikeres, csak valamiért nem töröljük az üzenetet - így az üzenet újra megjelenik.
Az in-flight üzenetek
Ugye ezek azok az üzenetek, amelyeknek a feldolgozása megkezdődött - legalábbis valaki elkérte az üzenetet az SQS-től, azán, hogy mit csinál vele, azt nem tudjuk. Az üzenet ilyenkor láthatatlan, és ha minden jól megy, egyszer a törlését is kéri majd valaki. Ilyen üzenetből egy Standard Queue-ban legfeljebb 120.000 lehet. Ha ezt a határt elértük, az SQS nem ad át újabb üzenetet feldolgozásra, amíg le nem dolgoztuk a lemaradást. Amennyiben ez gondot jelent, akkor vagy újabb consumereket kell munkába állítanunk, vagy több sort kell definiálnunk. Vagy kérjük a határ növelését az AWS-től, ez ugyanis nem hard limit.
És mi a helyzet, ha fontos az üzenetek sorrendje? Ha nem elég, ha az AWS "mident megtesz", hogy olyan sorrendben kapjuk meg az üzeneteket, ahogy a csőbe pumpáltuk őket? Akkor az SQS másik típusát, az SQS FIFO Queue-t kell használnunk. Erről lesz szó sorozatunk következő cikkében.