Amazon SAA-C03: Architektury bezserwerowe i sterowane zdarzeniami / Integracja API — Przewodnik do nauki

Część AWS SAA-C03 — Kompletny przewodnik do nauki. Ćwicz ze zweryfikowanymi odpowiedziami w centrum egzaminów Amazon, albo rozwiąż testy na czas na ExamRoll.io.

AWS Lambda: Model wykonania, cykl życia środowiska uruchomieniowego i zimne starty

Lambda wykonuje kod w izolowanych mikro-maszynach wirtualnych Firecracker, które działają zgodnie z dwufazowym cyklem życia. Faza INIT obejmuje provisionowanie kontenera, bootstrap środowiska uruchomieniowego, pobranie i rozpakowanie paczki wdrożeniowej oraz uruchomienie inicjalizacji na poziomie modułu — tworzenie klienta SDK, ładowanie sekretów odszyfrowanych przez KMS, konfigurację puli połączeń do bazy danych, ładowanie klas JVM i rozgrzewanie JIT. Faza INVOKE uruchamia handler. Zimny start (cold start) wiąże się z pełnym kosztem fazy INIT; ciepłe wywołanie (warm invocation) ponownie wykorzystuje to samo środowisko, więc wszystko, co jest buforowane poza handlerem (pule połączeń HTTP keep-alive, odszyfrowane sekrety, klienci baz danych), jest zachowywane między wywołaniami w tym samym kontenerze. Dlatego kanonicznym wzorcem jest tworzenie kosztownych obiektów w zakresie modułu i ich ponowne wykorzystywanie:

import boto3, os
ddb = boto3.client('dynamodb')          # reused across warm invokes
_secret = None
def _load_secret():
    global _secret
    if _secret is None:
        _secret = kms.decrypt(...)      # KMS call once per container, not per invoke
    return _secret

def handler(event, ctx):
    ...

Wielkość zimnego startu zależy od środowiska uruchomieniowego. Dla Node.js i Pythona są to dziesiątki do kilkuset milisekund; dla JVM i .NET czas ten może przekroczyć sekundę. Dla funkcji podłączonych do VPC, Hyperplane ENI w dużej mierze zamortyzowały historyczny narzut związany z dołączaniem ENI, ale rozmiar paczki i ciężki kod w fazie INIT nadal dominują.

Trzy narzędzia radzą sobie z zimnymi startami w różny sposób:

FunkcjaDziałanieKosztNajlepsze dopasowanie
Współbieżność na żądanie (On-demand)Domyślna; skaluje się przez początkowy burst ~500–3000, a następnie +500/minZa wywołanie + czas trwaniaRuch skokowy (bursty), tolerancja na opóźnienia
Współbieżność rezerwowana (Provisioned concurrency)Pre-inicjalizuje N środowisk, faza INIT zakończona przed nadejściem ruchuPłatność za zarezerwowane jednostki 24/7 + opłaty za wywołaniaRygorystyczne SLA dla p99 opóźnienia
SnapStart (Java, Python, .NET)Migawka (snapshot) Firecracker po fazie INIT; przywracana podczas zimnego startuBrak dodatkowych opłat dla Javy; niewielka opłata za buforowanie w innych przypadkachFunkcje Java, gdzie pełne provisionowanie jest nieefektywne kosztowo

SnapStart to opłacalne rozwiązanie dla obciążeń Java bez sztywnych wymagań dotyczących opóźnień — zimne starty spadają o około rząd wielkości bez dodatkowych opłat za wywołanie. Provisioned concurrency to właściwa odpowiedź, gdy synchroniczne API musi utrzymać p99 poniżej, powiedzmy, 100 ms podczas skoków ruchu; wymiarowanie go do p95 skoków niweluje problem opóźnień w ogonie rozkładu (tail-latency). Niedowymiarowanie go to klasyczny błąd: współbieżność na żądanie uruchamia nowe kontenery tylko wtedy, gdy nadejdzie żądanie, więc nagły wzrost ruchu powoduje wielosekundowe oczekiwanie dla prawdziwych użytkowników.

# SAM: SnapStart on a Java 17 function
MyJavaFn:
  Type: AWS::Serverless::Function
  Properties:
    Runtime: java17
    SnapStart: { ApplyOn: PublishedVersions }
    AutoPublishAlias: live

Sama współbieżność rezerwowana (Provisioned concurrency) może być skalowana za pomocą Application Auto Scaling — zaplanowana akcja zwiększająca liczbę jednostek z 10 do 200 o 07:45 i zmniejszająca ją z powrotem o 10:00 pozwala uniknąć płacenia za ciepłą pojemność w nocy, jednocześnie eliminując zimne starty podczas porannego szczytu.

Ustawienie pamięci jest jednocześnie pokrętłem do regulacji CPU: moc vCPU skaluje się liniowo z pamięcią do ok. 1769 MB na vCPU. Funkcja z na stałe ustawionymi 128 MB pamięci może w sumie kosztować więcej niż funkcja z 1024 MB, ponieważ dwukrotnie dłuższy czas wykonania często przewyższa dwukrotnie wyższą cenę za milisekundę. Nie zgaduj — użyj AWS Lambda Power Tuning, aby przetestować różne konfiguracje na reprezentatywnych danych wejściowych (payloads).

Kontrola współbieżności Lambda i ochrona systemów podrzędnych

Liczą się trzy mechanizmy kontroli współbieżności, a każdy z nich pełni inną funkcję:

Założenie, że Lambda “skaluje się w nieskończoność” pomija dwa ograniczenia. Po pierwsze, limit współbieżnych wykonań na poziomie konta jest realny, a limity skokowe (początkowo 500–3000 w zależności od Regionu, następnie +500/min) regulują tempo wzrostu. Po jego przekroczeniu, synchroniczni klienci otrzymują błąd 429 TooManyRequestsException, który API Gateway prezentuje jako błąd 5xx. Po drugie, systemy podrzędne mają własne limity: instancja db.t3.micro z max_connections=85 nie przetrwa tysiąca współbieżnych funkcji Lambda, z których każda otwiera połączenie. PostgreSQL tworzy oddzielny proces backendowy dla każdego połączenia, zużywając ~10 MB RAM; nawet przy wolnym CPU, samo nawiązywanie i zamykanie połączeń może zablokować instancję.

Dwa sposoby na złagodzenie tego problemu to (1) RDS Proxy, który puluje i multipleksuje wiele połączeń po stronie klienta na mały zestaw trwałych połączeń backendowych, oraz (2) wstawienie kolejki, aby tempo przetwarzania było oddzielone od tempa napływania żądań:

import psycopg2, os
conn = psycopg2.connect(
    host=os.environ['PROXY_ENDPOINT'],   # RDS Proxy, not the DB directly
    dbname='orders', user='app', password=get_secret())

RDS Proxy to rozwiązanie wymagające minimalnych zmian — sterownik i connection string prawie się nie zmieniają — co czyni je właściwą odpowiedzią, gdy wymaganiem jest “jak najmniejsza zmiana w aplikacji” plus problem wyczerpania połączeń. DynamoDB nie ma tego problemu: jego API oparte na HTTPS jest bezstanowe, dlatego DynamoDB naturalnie pasuje do obciążeń Lambda o wysokim stopniu rozproszenia (high-fanout).

Lambda: IAM, zmienne środowiskowe i sieć

Każda funkcja podczas wywołania przyjmuje rolę wykonawczą (execution role). Polityka zaufania (trust policy) roli przyznaje uprawnienie sts:AssumeRole usłudze lambda.amazonaws.com; jej polityka uprawnień (permission policy) definiuje, co funkcja może robić. Środowisko uruchomieniowe automatycznie wstrzykuje krótkotrwałe poświadczenia STS do zmiennych AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY i AWS_SESSION_TOKEN. Nigdy nie umieszczaj kluczy dostępu użytkownika IAM w zmiennych środowiskowych ani w kodzie — są statyczne, możliwe do odnalezienia w przypadku wycieku kodu źródłowego lub w eksportach CloudTrail, muszą być rotowane ręcznie i omijają cały model tymczasowych poświadczeń.

FnRole:
  Type: AWS::IAM::Role
  Properties:
    AssumeRolePolicyDocument:
      Statement:
      - Effect: Allow
        Principal: { Service: lambda.amazonaws.com }
        Action: sts:AssumeRole
    Policies:
      - PolicyName: ReadOrders
        PolicyDocument:
          Statement:
          - Effect: Allow
            Action: ["dynamodb:GetItem", "dynamodb:Query"]
            Resource: !GetAtt OrdersTable.Arn

Zmienne środowiskowe przechowujące wrażliwe dane konfiguracyjne powinny być szyfrowane kluczem KMS zarządzanym przez klienta (customer-managed KMS key), z użyciem „pomocników do szyfrowania w tranzycie” (helpers for encryption in transit), aby konsola szyfrowała dane po stronie klienta. Odszyfruj dane raz w fazie INIT i przechowuj czysty tekst w zmiennej na poziomie modułu — w przeciwnym razie każde wywołanie będzie wiązało się z kosztem wywołania API KMS.

Domyślnie funkcja działa w zarządzanym przez AWS VPC z nieograniczonym dostępem do internetu (outbound). Podłącz ją do własnego VPC tylko wtedy, gdy musi uzyskać dostęp do zasobów rezydujących w VPC (RDS w prywatnych podsieciach, ElastiCache, zasoby on-premise przez Direct Connect). Lambda dołącza wtedy interfejsy sieciowe Hyperplane ENI do wskazanych podsieci i dziedziczy ich routing.

Klasyczną pułapką jest umieszczenie Lambdy w prywatnej podsieci bez trasy dla ruchu do usług AWS, z wyjątkiem trasy przez bramkę NAT (NAT gateway) — lub, co gorsza, przez samodzielnie zarządzaną instancję NAT. Instancje NAT osiągają limit przepustowości pojedynczego interfejsu sieciowego (NIC), stanowią pojedynczy punkt awarii (SPOF) i są rozliczane za GB. Nawet bramki NAT naliczają opłaty za GB i są niepotrzebne dla ruchu do usług AWS. Prawidłowy wzorzec to:

To utrzymuje ruch wewnątrz sieci szkieletowej AWS, eliminuje limity przepustowości NAT i zapobiega niespodziewanym rachunkom za ruch wychodzący (egress). Należy pamiętać, że interfejsy ENI funkcji Lambda nigdy nie otrzymują publicznego adresu IP; umieszczenie funkcji w „publicznej” podsieci nie daje jej dostępu do internetu — nadal potrzebna jest bramka NAT w osobnej publicznej podsieci z odpowiednią trasą.

Amazon API Gateway: typy punktów końcowych, autoryzacja i dostarczanie

API Gateway oferuje trzy rodzaje API:

CechaREST APIHTTP APIWebSocket
OpóźnienieWyższe~60% niższeStanowe, dwukierunkowe
KosztWyższy~70% tańszeZa komunikat
Plany użycia / klucze APITakNieNie
Transformacje żądań/odpowiedzi (VTL)TakOgraniczone
Autoryzatory JWTPrzez LambdęNatywnePrzez Lambdę
WAFTakNie (użyj CloudFront jako frontu)Tak

Wybierz REST API, gdy potrzebujesz kluczy API i planów użycia, walidacji żądań za pomocą JSON Schema, szablonów mapowania VTL, autoryzatorów Cognito z zakresami (scopes) per metoda lub WAF; wybierz HTTP API dla lekkich wzorców proxy z uwierzytelnianiem JWT, gdzie koszt i opóźnienie mają większe znaczenie.

Typy punktów końcowych (endpoint types) określają, gdzie API jest udostępniane:

Wybór typu edge-optimized dla wewnętrznego API w jednym regionie dodaje niepotrzebny skok przez CloudFront i spowalnia propagację wdrożeń. Wybór typu regionalnego dla globalnie używanego publicznego API zmusza każde żądanie do podróży przez publiczny internet do jednego regionu.

Domeny niestandardowe (Custom domains) wymagają certyfikatów ACM, których lokalizacja zależy od typu punktu końcowego: us-east-1 dla edge-optimized (CloudFront jest globalny i tam terminuje TLS); region, w którym znajduje się API, dla punktów regionalnych. Pomylenie tego to częsta błędna konfiguracja. Mapowania ścieżek bazowych (Base path mappings) pozwalają jednej domenie obsługiwać wiele API (/orders → API zamówień, /users → API użytkowników).

Istnieją cztery modele autoryzacji, a omijanie wbudowanych mechanizmów jest klasycznym antywzorcem:

MechanizmKiedy używać
Autoryzacja IAMWywołujący to tożsamości AWS, które mogą podpisywać żądania SigV4 (inne usługi, SDK, komunikacja między kontami)
Autoryzator puli użytkowników CognitoUżytkownicy uwierzytelniają się w puli użytkowników Cognito; Gateway waliduje token JWT
Autoryzator LambdaNiestandardowe tokeny, zewnętrzni dostawcy tożsamości (IdP) bez OIDC, złożona logika per żądanie
Klucze API + plany użyciaPomiar użycia, ograniczanie (throttling), przydziały (quotas) — nigdy nie używane jako metoda uwierzytelniania

Niestandardowy autoryzator Lambda dodaje dodatkowe wywołanie na każde żądanie (lub na czas życia cache’a TTL), kolejną funkcję do utrzymania i monitorowania oraz ścieżkę kodu, w której błędy walidacji sygnatury mogą po cichu zezwolić na dostęp. Używaj go tylko wtedy, gdy wbudowane mechanizmy naprawdę nie są w stanie spełnić wymagań.

Integracja proxy z Lambdą (Lambda proxy integration) to domyślny wzorzec — całe żądanie jest przekazywane jako zdarzenie (event), a funkcja musi zwrócić odpowiedź w określonym formacie:

{
  "statusCode": 200,
  "headers": {"Content-Type": "application/json"},
  "body": "{\"orderId\":\"abc123\"}",
  "isBase64Encoded": false
}

Dla ingestii typu „fire-and-forget” przy bardzo wysokim TPS, użyj bezpośredniej integracji API Gateway z usługą AWS, aby przesyłać dane prosto do SQS lub Kinesis, całkowicie pomijając Lambdę. Eliminuje to zimne starty na ścieżce zapisu i oddziela tempo ingestii od mocy obliczeniowej przetwarzania.

Dla bezpiecznych wdrożeń użyj wdrożeń kanarkowych (canary deployments) na danym etapie (stage): procent ruchu jest kierowany do nowego wdrożenia, podczas gdy większość pozostaje na stabilnej wersji, a dedykowane metryki CloudWatch dla wdrożenia kanarkowego informują o decyzji o promocji lub wycofaniu.

aws apigateway update-stage --rest-api-id abc123 --stage-name prod \
  --patch-operations \
    op=replace,path=/canarySettings/percentTraffic,value=10 \
    op=replace,path=/canarySettings/deploymentId,value=xyz789

Dla prostego webhooka, gdzie cała otoczka API Gateway jest przesadą (np. jednorazowy callback ze Slacka, handler push z GitHuba), adresy URL funkcji Lambda (Lambda function URLs) zapewniają dedykowany punkt końcowy HTTPS bezpośrednio na funkcji. Zabezpiecz je za pomocą AuthType: AWS_IAM, gdy wywołujący to tożsamości AWS; jeśli AuthType to NONE, musisz walidować sygnaturę żądania wewnątrz funkcji. Adres URL funkcji z AuthType: NONE i bez weryfikacji wewnątrz funkcji to anonimowy punkt końcowy mocy obliczeniowej w publicznym internecie.

Typy wywołań, ponowienia i idempotentność

Źródła zdarzeń dzielą się na dwie kategorie o bardzo różnym zachowaniu. Źródła typu push (API Gateway, ALB, S3, SNS, EventBridge, Cognito) wywołują funkcję Lambda bezpośrednio i wymagają polityki opartej na zasobach (resource-based policy) typu AWS::Lambda::Permission, która nadaje uprawnienie lambda:InvokeFunction z odpowiednim Principal (np. events.amazonaws.com) i SourceArn. Bez niej reguła dopasowuje zdarzenia, ale każde wywołanie jest po cichu odrzucane — funkcja nigdy się nie uruchamia, a błędy pojawiają się tylko w CloudTrail. Jest to odrębne od roli wykonawczej (execution role), która określa, co funkcja może zrobić, a nie kto może ją wywołać.

Źródła typu poll (SQS, Kinesis, DynamoDB Streams, MSK) są odczytywane przez usługę Lambda za pomocą mapowania źródła zdarzeń (event source mapping) — nie jest wymagana polityka oparta na zasobach, ale rola wykonawcza musi nadawać uprawnienia do odczytu.

Typy wywołań dodatkowo różnicują zachowanie mechanizmu ponowień:

Ponieważ mechanizmy ponowień są wbudowane w każdą warstwę, idempotentność jest obowiązkowa, a nie opcjonalna. Wygaśnięcie visibility timeout w SQS podczas powolnego zapisu lub asynchroniczne ponowienie po błędzie 5xx w usłudze podrzędnej spowoduje powstanie duplikatów. Kanononiczny wzorzec wykorzystuje deterministyczny klucz i zapis warunkowy (conditional write) w DynamoDB:

def handler(event, context):
    msg_id = event['Records'][0]['messageId']
    try:
        ddb.put_item(
            TableName='processed',
            Item={'id': {'S': msg_id}, 'ttl': {'N': str(ttl)}},
            ConditionExpression='attribute_not_exists(id)')
    except ddb.exceptions.ConditionalCheckFailedException:
        return  # already processed
    process(event)

Dekorator @idempotent z AWS Lambda Powertools implementuje dokładnie ten wzorzec, wykorzystując DynamoDB jako backend.

Odsprzęganie za pomocą SQS i SNS

Podłączanie źródeł typu push o wysokim współczynniku rozgałęzienia (high-fanout) bezpośrednio do Lambdy jest kruche. Powiadomienia o zdarzeniach z S3, na przykład, są synchroniczne dla każdego zdarzenia i podlegają limitowi współbieżności (concurrency ceiling) Lambdy; jeśli liczba wywołań przekroczy dostępną współbieżność podczas gwałtownego napływu danych (np. kampania marketingowa wrzucająca tysiące dokumentów w ciągu kilku sekund), okno ponowień S3 jest krótkie, a zdarzenia mogą zostać skutecznie utracone. Rozwiązaniem jest bufor:

WzorzecKiedy stosować
S3 → Lambda (bezpośrednio)Niski, przewidywalny ruch; idempotentne przetwarzanie
S3 → SQS → LambdaNierównomierne obciążenie (bursty workloads); potrzeba ponowień/DLQ; limity w usługach podrzędnych
S3 → SNS → wiele kolejek SQSFan-out do kilku niezależnych konsumentów
S3 → EventBridge → wiele celówRouting między kontami; filtrowanie oparte na treści

SNS to model pub/sub: jedna publikacja, wielu subskrybentów (SQS, Lambda, HTTPS, e-mail). Filtrowanie wiadomości opiera się na atrybutach. SQS to trwała kolejka point-to-point przechowująca wiadomości do 14 dni. Najpopularniejszym połączeniem jest fan-out SNS → SQS, co daje każdemu konsumentowi własną buforowaną kolejkę do niezależnego skalowania i ponownego odtwarzania zdarzeń.

Dla ścisłej kolejności (np. zamówienia danego klienta przetwarzane sekwencyjnie), użyj kolejki SQS FIFO z MessageGroupId ustawionym na klucz porządkujący. Wiadomości w obrębie jednej grupy są dostarczane w kolejności; różne grupy są przetwarzane równolegle. Standardowa kolejka SQS zapewnia jedynie kolejność typu „best-effort” (bez gwarancji).

Kanononiczny, odsprzęgnięty wzorzec przyjmowania danych wykorzystuje bezpośrednią integrację API Gateway z SQS do absorbowania nagłych skoków ruchu oraz procesor z ograniczoną szybkością przetwarzania:

Resources:
  OrdersQueue:
    Type: AWS::SQS::Queue
    Properties:
      FifoQueue: true
      ContentBasedDeduplication: true
      RedrivePolicy:
        deadLetterTargetArn: !GetAtt OrdersDLQ.Arn
        maxReceiveCount: 5

  ProcessorFunction:
    Type: AWS::Lambda::Function
    Properties:
      ReservedConcurrentExecutions: 20   # cap the DB write rate

  Mapping:
    Type: AWS::Lambda::EventSourceMapping
    Properties:
      EventSourceArn: !GetAtt OrdersQueue.Arn
      FunctionName: !Ref ProcessorFunction
      BatchSize: 10

Rezerwacja współbieżności (reserved concurrency) jest celowa — ogranicza szybkość zapisów do bazy danych, dzięki czemu to kolejka (a nie RDS) absorbuje nagły wzrost ruchu. Nieprzetworzone wiadomości po przekroczeniu maxReceiveCount trafiają do DLQ w celu analizy offline.

EventBridge: Reguły, transformacja danych wejściowych i cele API (API Destinations)

EventBridge to szyna zdarzeń (event bus) świadoma schematów, oferująca zaawansowane dopasowywanie wzorców JSON, źródła od partnerów SaaS, rejestr schematów oraz archiwizację i ponowne odtwarzanie zdarzeń. Reguły dopasowują zdarzenia na podstawie wzorców i rozsyłają je do ponad 30 typów celów (Lambda, Step Functions, SQS, Kinesis, ECS, Firehose), z filtrowaniem opartym na treści wiadomości — a nie tylko na atrybutach jak w SNS:

{
  "source": ["tenant.energy"],
  "detail-type": ["UsageReported"],
  "detail": { "kWh": [{ "numeric": [">", 100] }] }
}

Jedna reguła może mieć do pięciu celów, z których każdy otrzymuje albo surowe zdarzenie, albo jego przetworzony podzbiór. Transformatory wejściowe (Input transformers) wymuszają luźne powiązania (loose coupling): InputPathsMap wyodrębnia ścieżki JSON ze zdarzenia, a InputTemplate przekształca je w format oczekiwany przez docelową usługę:

EventPattern:
  source: ["com.acme.orders"]
  detail-type: ["OrderPlaced"]
Targets:
  - Arn: !GetAtt PaymentValidator.Arn
    InputTransformer:
      InputPathsMap:
        orderId: "$.detail.orderId"
        amount: "$.detail.total"
        card: "$.detail.payment.cardToken"
      InputTemplate: |
        {"orderId": <orderId>, "amount": <amount>, "cardToken": <card>}

Każda funkcja Lambda walidująca otrzymuje tylko te dane, których potrzebuje; walidator adresu nigdy nie widzi tokenu karty. Jest to zdecydowanie lepsze rozwiązanie niż monolityczna funkcja Lambda, która otrzymuje pełne zdarzenie i rozgałęzia logikę wewnętrznie — monolit koncentruje uprawnienia IAM (jedna rola musi posiadać wszystkie uprawnienia do usług podrzędnych), zwiększa promień rażenia błędu (blast radius), uzależnia od siebie cykle wdrożeniowe, uniemożliwia dostosowanie pamięci/timeoutu dla poszczególnych zadań i wymusza skalowanie całej funkcji do poziomu wymaganego przez najbardziej obciążoną gałąź logiki.

Cele API (API destinations) odwracają kierunek: EventBridge wywołuje zewnętrzny punkt końcowy HTTPS. W połączeniu z połączeniem (connection), które przechowuje dane uwierzytelniające (Basic, klucz API lub OAuth) w Secrets Manager, jest to bezserwerowy sposób na powiadamianie zewnętrznej usługi SaaS, gdy np. zadanie AWS Batch zakończy się sukcesem — bez potrzeby użycia funkcji Lambda. EventBridge przechwytuje zdarzenie zmiany stanu, reguła dopasowuje JobSucceeded, a cel typu API destination wysyła żądanie POST do dostawcy z danymi uwierzytelniającymi wstrzykniętymi z połączenia.

Reguły harmonogramu (Scheduled rules) (wyrażenia cron/rate) lub nowszy EventBridge Scheduler zastępują instancje EC2 typu „heartbeat” do cyklicznych zadań — nocnych raportów, cogodzinnego odświeżania pamięci podręcznej.

Wybierz EventBridge zamiast SNS, gdy filtrowanie opiera się na treści wiadomości (a nie tylko na atrybutach), gdy nowi konsumenci muszą mieć możliwość podłączenia się w przyszłości bez zmian po stronie producenta lub gdy routing obejmuje wiele kont lub źródeł SaaS. Wybierz SNS, gdy fan-out jest prostym powiadomieniem filtrowanym po atrybutach do stałego zestawu subskrybentów.

Step Functions: Orkiestracja i Distributed Map

Gdy przepływ pracy ma więcej niż kilka kroków, rozgałęzienia, ponowne próby, ręczne zatwierdzenie lub długie oczekiwanie, osadzanie tej logiki w łańcuchu funkcji Lambda staje się niemożliwe do utrzymania. Step Functions eksternalizuje maszynę stanów w języku Amazon States Language.

Każde zadanie powinno jawnie deklarować Retry i Catch:

"ValidatePayment": {
  "Type": "Task",
  "Resource": "arn:aws:states:::lambda:invoke",
  "Parameters": {"FunctionName": "PaymentValidator", "Payload.$": "$"},
  "Retry": [{
    "ErrorEquals": ["Lambda.ServiceException", "Lambda.TooManyRequestsException"],
    "IntervalSeconds": 2, "MaxAttempts": 4, "BackoffRate": 2.0
  }],
  "Catch": [{"ErrorEquals": ["PaymentDeclined"], "Next": "RefundStep"}],
  "Next": "ShipOrder"
}

Stany Parallel i Map uruchamiają gałęzie współbieżnie i agregują wyniki — co idealnie pasuje do systemów zamówień z niezależnymi walidatorami (adres, stan magazynowy, płatność). Stan między krokami przepływa przez dokument JSON wykonania, eliminując potrzebę posiadania współdzielonej bazy danych używanej wyłącznie do koordynacji przepływu pracy.

Wzorzec .waitForTaskToken wstrzymuje wykonanie do momentu, gdy zewnętrzny aktor wywoła SendTaskSuccess z tokenem — jest to kanoniczne rozwiązanie, gdy przepływ pracy obejmuje Lambdy, EC2, kontenery, systemy on-premise i wymaga ręcznego zatwierdzenia przy minimalnym obciążeniu operacyjnym:

"ManagerApproval": {
  "Type": "Task",
  "Resource": "arn:aws:states:::sns:publish.waitForTaskToken",
  "Parameters": {
    "TopicArn": "arn:aws:sns:us-east-1:111:approvals",
    "Message": { "TaskToken.$": "$$.Task.Token", "OrderId.$": "$.orderId" }
  },
  "Next": "Fulfill"
}

Distributed Map rozszerza standardowy stan Map, aby przetwarzać do 10 000 równoległych wykonań podrzędnych i może iterować bezpośrednio po obiektach w buckecie S3 lub wierszach w pliku CSV/JSONL, z automatycznym grupowaniem (batching), checkpointingiem i tolerancją na błędy. W przypadku tysięcy obiektów S3 o częściowo ustrukturyzowanej formie jest to najbardziej wydajna operacyjnie opcja — wskaż prefiks, zdefiniuj zadanie dla pojedynczego elementu, a Step Functions zajmie się rozproszeniem (fan-out), MaxConcurrency, ponownymi próbami i agregacją wyników:

{
  "Type": "Map",
  "ItemReader": {
    "Resource": "arn:aws:states:::s3:listObjectsV2",
    "Parameters": { "Bucket": "raw-events", "Prefix": "2024/" }
  },
  "MaxConcurrency": 1000,
  "ItemProcessor": {
    "ProcessorConfig": { "Mode": "DISTRIBUTED", "ExecutionType": "STANDARD" },
    "StartAt": "ProcessObject",
    "States": { "ProcessObject": { "Type": "Task", "Resource": "arn:aws:lambda:...:function:ProcessOne", "End": true } }
  }
}

Odtworzenie tego samego na SQS lub EventBridge wymaga niestandardowego śledzenia ukończenia, ponownych prób i składania wyników.

Step Functions vs. EventBridge: Step Functions jest właściwym wyborem, gdy Ty jesteś właścicielem sekwencji i wyniku — stanu, rozgałęzień, ponownych prób, zatwierdzeń. EventBridge jest właściwym wyborem, gdy producenci nie wiedzą ani nie dbają o to, kto jest konsumentem, a konsumenci podłączają się niezależnie.

S3 Event Notifications

Do przetwarzania przesłanych plików w czasie zbliżonym do rzeczywistego skonfiguruj powiadomienia o zdarzeniach S3 na s3:ObjectCreated:* (lub na konkretny wariant, taki jak Put, Post, CompleteMultipartUpload) z docelową funkcją Lambda — z uwzględnieniem powyższych zastrzeżeń dotyczących nagłych wzrostów ruchu. Zabezpieczenia:

Przetwarzanie strumieniowe: Kinesis Data Streams vs. Firehose

Kinesis Data Streams (KDS) to partycjonowany, uporządkowany, odtwarzalny log z retencją od 24 godzin do 365 dni. Kolejność jest zachowana w obrębie partycji (shard), kluczowana przez klucz partycji — co jest kluczowe dla agregacji per urządzenie lub per tenant. Wielu konsumentów odczytuje dane niezależnie (enhanced fan-out zapewnia izolowaną przepustowość dla każdego konsumenta). Wybierz KDS, gdy potrzebujesz uporządkowanego odtwarzania, wielu niezależnych konsumentów lub wysokiej przepustowości na partycję.

Kinesis Data Firehose to w pełni zarządzany strumień dostarczający dane do S3, Redshift, OpenSearch lub Splunk, z wbudowanym buforowaniem (60 s lub 1–128 MB), opcjonalną transformacją Lambda, kompresją (GZIP, Snappy) i konwersją do formatu Parquet/ORC. Nie ma partycji do zarządzania. Firehose to wybór wymagający niewielkiego nakładu pracy operacyjnej, gdy niestandardowi konsumenci i odtwarzanie nie są potrzebne — a jedynie dostarczanie danych w czasie zbliżonym do rzeczywistego.

Kanoniczny potok analityczny działający w czasie zbliżonym do rzeczywistego to producenci → KDS → Firehose → S3 (Parquet) → Athena/QuickSight, z opcjonalnym wzbogacaniem danych przez Lambdę w Firehose.

AWS Transfer Family dla zarządzanego SFTP

Gdy partnerzy wymagają przesyłania plików przez SFTP, FTPS lub FTP do lub z S3 lub EFS, AWS Transfer Family zapewnia zarządzany, działający w wielu strefach dostępności (multi-AZ) punkt końcowy, który obsługuje protokoły już używane przez klientów. Uwierzytelnianie obsługuje użytkowników zarządzanych przez usługę, klucze SSH lub niestandardowych dostawców tożsamości (IdP) za pośrednictwem API Gateway/Lambda. Pliki trafiają bezpośrednio do S3 z zastosowanym szyfrowaniem SSE i politykami cyklu życia; polityki IAM zawężające uprawnienia (scope-down policies) ograniczają każdego użytkownika do określonego prefiksu.

Budowanie tego samodzielnie na EC2 wymaga wzmacniania bezpieczeństwa OpenSSH, wdrażania poprawek, zapewnienia wysokiej dostępności (HA) w wielu strefach AZ, rotacji kluczy i przesyłania logów — wszystko to przejmuje na siebie Transfer Family. Wybierz tę usługę, gdy wymaganiem jest „partnerzy przesyłają nam pliki przez SFTP”, a chcesz, aby pliki trafiały do S3 przy minimalnym obciążeniu operacyjnym.

Komponowanie kanonicznego wzorca serverless

Projekt pozyskiwania danych o niskim narzucie operacyjnym dla cogodzinnych metryk per tenant: czujniki wysyłają żądania POST do API Gateway (HTTP API, regionalne)Lambda waliduje i publikuje do EventBridge → reguły kierują ruch do Lambdy zapisującej do DynamoDB (ID tenanta jako klucz partycji, kubełek godzinowy jako klucz sortowania) oraz, równolegle, do Firehose → S3 (Parquet) w celach analitycznych. Nowi konsumenci dołączają jako dodatkowe reguły EventBridge bez ingerencji w producentów — jest to wymóg rozszerzalności, którego sam SNS nie spełniłby tak elegancko. Tam, gdzie liczy się stała przepustowość i kolejność (uzgadnianie rozliczeń, strumienie zdarzeń finansowych), zastąp EventBridge usługą Kinesis Data Streams i użyj enhanced fan-out dla niezależnych konsumentów.

Katalog pułapek: Dlaczego popularne antywzorce zawodzą

Instancja/bramka NAT dla ruchu do usług AWS z funkcji Lambda w podsieci prywatnej. Instancje NAT ograniczają przepustowość do jednej karty sieciowej EC2 i są pojedynczym punktem awarii (SPOF); bramki NAT są rozliczane za GB. Oba rozwiązania są niepotrzebne w przypadku ruchu do usług AWS. Użyj gateway endpoints dla S3/DynamoDB i interface endpoints dla wszystkich pozostałych usług.

Ignorowanie zimnych startów w API o krytycznym znaczeniu dla opóźnień. Tryb on-demand alokuje kontenery dopiero po nadejściu żądania, więc nagłe skoki ruchu powodują niedotrzymanie umów SLA. Dostosuj provisioned concurrency do wartości p95 skoków ruchu; użyj SnapStart dla workloadów Java bez rygorystycznych umów SLA.

Monolityczna funkcja Lambda, która odbiera pełne zdarzenie i wewnętrznie rozgałęzia logikę. Narusza zasadę najmniejszych uprawnień (jedna rola posiada wszystkie uprawnienia do usług podrzędnych), wiąże ze sobą cykle wdrożeń, uniemożliwia strojenie wydajności per logika i skaluje całą funkcję do poziomu wymaganego przez najbardziej obciążającą gałąź. Podziel funkcję według odpowiedzialności; połącz je za pomocą EventBridge lub Step Functions.

Bezpośrednie połączenia do bazy danych z wielu funkcji Lambda. Całkowita liczba połączeń jest równa liczbie współbieżnych wywołań, ponieważ kontenery nie współdzielą pul połączeń. Rozwiąż ten problem za pomocą RDS Proxy (pooling), reserved concurrency (limitowanie wywołań) lub SQS (buforowanie).

Synchroniczna funkcja Lambda do obsługi gwałtownych skoków danych wejściowych. Przekroczenie limitu współbieżności zwraca błąd 429 do API Gateway i 5xx do klientów; bezpośrednie powiadomienia z S3 podczas skoków ruchu po cichu odrzucają zdarzenia. Wstaw kolejkę SQS lub użyj bezpośredniej integracji API Gateway → SQS.

Publiczne adresy URL funkcji Lambda z AuthType: NONE i bez walidacji sygnatury wewnątrz funkcji. Anonimowe zasoby obliczeniowe w publicznym internecie. Użyj AWS_IAM dla wywołań z AWS lub waliduj sygnatury dla webhooków od stron trzecich.

Niestandardowy authorizer Lambda tam, gdzie wystarczyłby wbudowany. Dodaje opóźnienie, kolejną funkcję do utrzymania i ścieżkę kodu, w której błędy weryfikacji sygnatury mogą po cichu zezwolić na dostęp. Preferuj autoryzację IAM dla podmiotów AWS; authorizer Cognito dla pul użytkowników.

Niewłaściwy region certyfikatu ACM dla domen niestandardowych. Punkty końcowe typu Edge-optimized wymagają certyfikatu w regionie us-east-1; punkty regionalne w regionie, w którym znajduje się API.

Brak AWS::Lambda::Permission dla źródeł typu push (EventBridge, S3, SNS). Zdarzenia pasują do reguł, ale wywołania są po cichu odrzucane. To co innego niż rola wykonawcza (execution role) — to uprawnienie określa, kto może wywołać funkcję, a nie co funkcja może zrobić.

Brak idempotencji. Każda warstwa ponawia próby — wywołania asynchroniczne, ponowne dostarczanie wiadomości SQS po wygaśnięciu visibility timeout, ponawianie w batchach Kinesis. Bez deterministycznego klucza deduplikacji i zapisu warunkowego, duplikaty są nieuniknione.


Kontenery i orkiestracja · Wszystkie domeny · Pamięć masowa i cykl życia danych

Przećwicz te pytania → · Testy na czas na ExamRoll.io →

Pass the whole exam — not just this question

You found this answer. Get every verified question and explanation in one place, and save hours of prep. Free to start.

Zdaj egzamin →

Przeglądaj Amazon →

Related guides

Dostęp all-in-one

Jedna subskrypcja. Każdy egzamin.

Każdy plan odblokowuje nieograniczone wyszukiwanie odpowiedzi, testy praktyczne, wyjaśnienia AI i pełną bibliotekę zasobów — w ponad 20 językach.

Miesięczny
24.87
Just €0.83/day
Wszystko w cenie:
  • Nieograniczone wyszukiwanie odpowiedzi
  • Nieograniczone testy praktyczne
  • Wyjaśnienia wspomagane AI
  • Pełna biblioteka zasobów
  • Ponad 20 języków
  • Cotygodniowe aktualizacje treści
  • Nagrody i polecenia
  • Priorytetowe wsparcie
Rozpocznij bezpłatny okres próbny

Karta kredytowa nie jest wymagana*

Najlepsza wartość
12 miesięcy
179.87
Just €0.49/daySave 40%
Wszystko w cenie:
  • Nieograniczone wyszukiwanie odpowiedzi
  • Nieograniczone testy praktyczne
  • Wyjaśnienia wspomagane AI
  • Pełna biblioteka zasobów
  • Ponad 20 języków
  • Cotygodniowe aktualizacje treści
  • Nagrody i polecenia
  • Priorytetowe wsparcie
Rozpocznij bezpłatny okres próbny

Karta kredytowa nie jest wymagana*

✓ Plan darmowy w zestawie · ✓ Anuluj w dowolnym momencie · ✓ Wszystkie plany odblokowują pełny produkt