SQS + Lambda er mye brukt i AWS verden for å skape skalerbare systemer. Argumentene fra AWS forteller at denne kombinasjonen løser skalerbarhet, asynkron behandling, feilhåndtering, kostandseffektivitet, enkel integrasjon og pålitelighet.
Erfaringsmessig er dette riktig.
Antall samtidige 'eventer' som behandles i en lambda funksjon kan bli mange, så hva skjer med da med ressurser som funksjonen bruker? Om funksjonen kaller på et api, vil det klare å ta unna trafikken,
eller vil det gå i sirup? Om du bruker en database, vil den håndtere et par hundre samtidige connections?
Det er mulig å begrense antall samtidige instanser av en lambda funksjon. Men en mer effektiv måte vil ofte være å ta inn flere eventer samtidig, og iterere over disse.
Men da må vi sikre at vi har god kontroll på hvilke eventer som feilet, og hvilke som gikk bra. De som feilet ønsker vi ofte å behandle en gang til, eventuelt putte på dead-letter køen som du selfølgelig har definert.
Selv om du har vært flink med å lage en idempotent funksjon, er det sjelden du ønsker å behandle eventer flere ganger om det er mulig å unngå.
Om du bare kaster en feil ut av funksjonen ved problemer med en av meldingene, vil alle meldingene komme inn igjen, så her er det muligheter for duplikat behandling.
Her har AWS kommet opp med en grei løsning som gjør at runtimen er i stand til å tolke hvilke meldinger som feilet.
Template.yaml
Events:
GiftHandlingFunctionQueueEvent:
Type: SQS
Properties:
BatchSize: 100
MaximumBatchingWindowInSeconds: 30
Enabled: True
Queue: !GetAtt GiftHandlingFunctionQueue.Arn
FunctionResponseTypes:
- ReportBatchItemFailures
Her er indikerer vi til aws at vi kommer til å bruke ReportBatchItemFailures.
Eksempel kode snippet:
def gift_lambda_handler(event, context):
if event:
batch_item_failures = []
sqs_batch_response = {}
for giftRecord in event["Records"]:
try:
# process message
except Exception as e:
batch_item_failures.append({"itemIdentifier": giftRecord['messageId']})
sqs_batch_response["batchItemFailures"] = batch_item_failures
return sqs_batch_response
Her bruker vi ReportBatchItemFailures.
Avhengig av antall retries som er konfigurert, vil nå runtimet enten sørge for at meldingen dukker opp i et annet kall til funksjonen, eller for eksempel legge meldingen som feilet på dead-letter køen.
God jul!