Czy funkcja Lambda AWS może wywoływać inną

320

Mam 2 funkcje Lambda - jedną, która tworzy wycenę, i jedną, która przekształca wycenę w zamówienie. Chciałbym, aby funkcja Order lambda wywołała funkcję Quote, aby zregenerować ofertę, a nie tylko otrzymywać ją od niezaufanego klienta.

Szukałem wszędzie, o czym myślę - ale nie widzę, jak poszedłbym do łączenia lub wywoływania funkcji ... na pewno to istnieje!

Srebro
źródło
1
Sięgam tutaj, ale dlaczego nie mogłeś polegać na AWS JavaScript SDK w pierwszej funkcji Lambda, stworzyć klienta AWS.Lambda i wywołać drugą funkcję?
devonlazarus
Właśnie tego chciałem spróbować - ale nie byłem do końca pewien, jak sobie z tym poradzić, ponieważ nie było żadnych przykładów robienia tego z innej funkcji Lambda.
Srebrny
1
najwyraźniej można również wywołać funkcję Lambda przez HTTP .
devonlazarus
4
i jeszcze jeden pomysł, możesz
połączyć
6
Innymi częstymi alternatywami nie wymienionymi tutaj są Funkcje kroku lub SWF.
lebryant

Odpowiedzi:

365

Znalazłem sposób, używając aws-sdk.

var aws = require('aws-sdk');
var lambda = new aws.Lambda({
  region: 'us-west-2' //change to your region
});

lambda.invoke({
  FunctionName: 'name_of_your_lambda_function',
  Payload: JSON.stringify(event, null, 2) // pass params
}, function(error, data) {
  if (error) {
    context.done('error', error);
  }
  if(data.Payload){
   context.succeed(data.Payload)
  }
});

Dokument można znaleźć tutaj: http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/Lambda.html

Nicolas Grenié
źródło
28
Korzystanie z SNS jest prawdopodobnie lepszym rozwiązaniem, ale jest to poprawna odpowiedź.
Srebrny
29
Mogę się mylić, ale myślę, że ponieważ wywołanie jest synchroniczne, pierwsza lambda czeka na zakończenie drugiej lambdy, więc naliczane będą opłaty, gdy oba lambda są uruchomione. przy użyciu SNS, pierwsza lambda powinna zakończyć się i pozwolić drugiej lambda na wykonanie niezależne.
dev
81
Udało mi się to uruchomić dzięki InvocationType: 'Event'parametrowi (dodaj go po FunctionNamei Payload). Z dokumentacji: „Możesz opcjonalnie zażądać wykonania asynchronicznego, określając Zdarzenie jako InvocationType”. W przypadku wykonywania asynchronicznego funkcja wywołania zwrotnego zostanie niezawodnie wywołana, ale bez konieczności oczekiwania na zakończenie wywołanej lambdy.
Alessandro
25
Zauważ, że rola wywołującej funkcji lambda musi uwzględniać zasady IAM AWSLambdaRole. Lub możesz dodać następujący obiekt instrukcji do istniejącej polityki roli: „{„ „Efekt”: „Zezwól”, „Akcja”: [„lambda: InvokeFunction”], „Zasób”: [„*”]} `
Bob Arlof
4
W rzeczywistości AWS wydało StepFunctions, które pozwalają na wywołanie wielu lambda bez konieczności wywoływania lambda z innej lambda, tak że np. pierwszy nie „czeka”, aż drugi się skończy
Sebastien H.,
116

Powinieneś połączyć swoją sieć Lambda functionsprzez SNS. Takie podejście zapewnia dobrą wydajność, opóźnienia i skalowalność przy minimalnym wysiłku.

Twoja pierwsza Lambdapublikuje wiadomości do Ciebie, SNS Topica druga Lambdasubskrybuje ten temat. Gdy tylko wiadomości dotrą do tematu, sekunda Lambdazostanie wykonana z komunikatem jako parametrem wejściowym.

Zobacz Wywoływanie funkcji Lambda za pomocą powiadomień Amazon SNS .

Możesz także użyć tego podejścia do wywoływania funkcji Lambda dla wielu kont za pośrednictwem SNS .

kixorz
źródło
2
Kineza może być nieco bardziej skomplikowana, ale jeśli szukasz bardziej niezawodnego rozwiązania, może to być dla ciebie dobra opcja. Ponadto SNS nie przechowuje zdarzeń przychodzących, tak robi Kinesis.
kixorz
7
„Powinieneś połączyć swoje funkcje Lambda przez SNS” - ​​czy możesz to wesprzeć dowodami / linkami do dokumentów? Widzę, jak działałyby obie metody, chciałbym zobaczyć opinie / określone stwierdzenia, które z nich są preferowane
Claude,
30
To dobry pomysł, jeśli potrzebujesz, aby był asynchroniczny. Ale jeśli twoja pierwsza funkcja lambda potrzebuje zwracanej wartości z drugiej lambda, musisz połączyć łańcuch lambdas i pierwsza funkcja lambda wywoła bezpośrednio drugą funkcję lambda.
Noel Llevares,
3
Nie polecałbym używania SNS. Możesz po prostu użyć funkcji API asynchronicznego wywołania dla funkcji lambda - nie ma powodu, aby używać SNS, chyba że chcesz powiadomić wielu subskrybentów, a nie tylko wywołać inną funkcję lambda.
6
Pamiętaj, że SNS nie ma gwarancji doręczenia, więc możesz wysłać wiadomość, ale może ona nie dotrzeć.
Bart Van Remortele
79

Oto przykładowy kod dla Pythona,

from boto3 import client as boto3_client
from datetime import datetime
import json

lambda_client = boto3_client('lambda')

def lambda_handler(event, context):
    msg = {"key":"new_invocation", "at": datetime.now()}
    invoke_response = lambda_client.invoke(FunctionName="another_lambda_",
                                           InvocationType='Event',
                                           Payload=json.dumps(msg))
    print(invoke_response)

Przy okazji, musisz również dodać taką politykę do swojej roli lambda

   {
        "Sid": "Stmt1234567890",
        "Effect": "Allow",
        "Action": [
            "lambda:InvokeFunction"
        ],
        "Resource": "*"
    }
blueskin
źródło
Dokumentacja wydaje się sugerować, że ładunek musi być JSON. Czy można wysyłać dane binarne?
mbatchkarov
2
Ja też wolę tę metodę, ale ma jedną usterkę. Musisz przekonwertować datetime.now()ciąg (lub jakoś go obsłużyć). W przeciwnym razie pojawia się błąddatetime.datetime(2017, 9, 11, 14, 40, 53, 23834) is not JSON serializable
John C
Czy można być bardziej restrykcyjnym w roli pierwszej lambdy? Czyli, aby ograniczyć to do wywoływania określonych funkcji, a nie wszystkich?
Phil
@Phil może pole „Zasób” może być ustawione tak, aby zezwalało tylko na określony zestaw funkcji, nie jestem jednak całkowicie pewien
blueskin 30.01.2018
2
InvocationTypePowinno być: RequestResponse. Aby uzyskać odpowiedź od lambda, którą próbujesz wywołać.
ambigus9,
31

Od czasu zadania tego pytania firma Amazon wydała funkcje krokowe ( https://aws.amazon.com/step-functions/ ).

Jedną z podstawowych zasad AWS Lambda jest to, że można skupić się bardziej na logice biznesowej, a mniej na logice aplikacji, która łączy to wszystko razem. Funkcje krokowe pozwalają koordynować złożone interakcje między funkcjami bez konieczności pisania kodu w tym celu.

dustinnoe
źródło
12

To rozwiązanie zostało wykonane przy użyciu boto3 i Python:

import boto3
import json

invokeLambda = boto3.client('lambda', region_name='eu-west-1')

def lambda_handler(event, context):
    invokeLambda.invoke(FunctionName = 'function_name', InvocationType = 'RequestResponse', Payload = json.dumps(event))

    return True
Trilok Nagvenkar
źródło
2
InvocationType Wybierz jedną z następujących opcji. RequestResponse (domyślnie) - Wywołuje funkcję synchronicznie. Pozostaw połączenie otwarte, dopóki funkcja nie zwróci odpowiedzi lub upłynie limit czasu. Zdarzenie - Wywołaj funkcję asynchronicznie. Wysyłaj zdarzenia, które wielokrotnie nie powiodły się, do kolejki niedostarczonych funkcji (jeśli skonfigurowano). DryRun - sprawdź wartości parametrów i sprawdź, czy użytkownik lub rola ma uprawnienia do wywołania funkcji.
Trilok Nagvenkar
11

Patrzyłem na wyłączenie SNS, dopóki nie zobaczyłem tego w dokumentacji klienta Lambda (wersja Java) :

Klient uzyskujący dostęp do AWS Lambda. Wszystkie zgłoszenia serwisowe wykonane przy użyciu tego klienta są blokowane i nie będą zwracane, dopóki zgłoszenie serwisowe się nie zakończy.

Tak więc SNS ma oczywistą zaletę: jest asynchroniczny. Twoja lambda nie będzie czekać na zakończenie kolejnej lambda.

Ben Iggulden
źródło
17
InvocationType = 'Event' sprawia, że ​​jest asynchroniczna. docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/…
Ankit
3
@Zestaw, który powinien być wybraną odpowiedzią, wprowadzono mnie w błąd, że użycie SNS było jedynym sposobem na wywołanie asynchroniczne, ponieważ nikt nie odpowiedział na te informacje.
@Ankit, czy znasz przykład użycia InvocationType = 'Event', ale z Java zamiast JavaScript? Istnieje mnóstwo dokumentacji Java, ale nie tak wiele przykładów, jak JavaScript
Talador12
SNS wciąż dodaje koszty za jego użytkowanie
Sebastien H.,
1
@SebastienH. Wywołanie Lambda przez SNS nie wiąże się z żadnymi kosztami. aws.amazon.com/sns/pricing
fabdouglas
8

Amazon wprowadził funkcje kroków w AWS lambda w 2016 roku. Myślę, że teraz wygodniej jest korzystać z funkcji kroków, ponieważ jest bardzo łatwa w użyciu. Możesz zbudować maszynę stanową z dwiema funkcjami lambda jako:

  • do wyceny
  • zamienia wycenę w zamówienie

Możesz to łatwo zrobić, jak poniżej:

Tutaj możesz ustawić pierwszy stan na wycenę, a drugi na kolejność

{
  Comment: "Produce a quote and turns into an order",
  StartAt: "ProduceQuote",
  States: {
    ProduceQuote: {
      "Type": Task,
      "Resource": "arn:aws:lambda:us-east-1:123456789012:function:ProduceQuote",
      "next": TurnsToOrder
    }
    TurnsToOrder: {
      Type: Task,
      Resource: "arn:aws:lambda:us-east-1:123456789012:function:ProduceQuote",
      end: true
    }
  }
}

Funkcje Steps naprawdę ułatwiają pisanie wielu funkcji lambda i uruchamianie ich w sekwencji lub równolegle. Możesz uzyskać więcej informacji o funkcjach kroków lambda tutaj: Funkcje kroków

Sunil Kapil
źródło
5

Pracowałem z odpowiedzią dostarczoną przez blueskin, ale nie mogłem odczytać odpowiedzi ładunku, ponieważ InvocationType = 'Event' jest asynchroniczne , więc zmieniłem się na InvocationType = 'RequestResponse' i teraz wszystko działa dobrze.

Antonio
źródło
5

W java możemy wykonać następujące czynności:

AWSLambdaAsync awsLambdaAsync = AWSLambdaAsyncClientBuilder.standard().withRegion("us-east-1").build();

InvokeRequest invokeRequest = new InvokeRequest();
invokeRequest.withFunctionName("youLambdaFunctionNameToCall").withPayload(payload);

InvokeResult invokeResult = awsLambdaAsync.invoke(invokeRequest); 

Tutaj ładunek jest twoim strunowym obiektem java, który musi zostać przekazany jako obiekt Json do innej lambda na wypadek, gdybyś musiał przekazać pewne informacje z wywołania lambda do wywoływanej lambda.

Suyash
źródło
2

Można wywołać funkcję lambda bezpośrednio (przynajmniej za pośrednictwem Java) stosując AWSLambdaClientsposób opisany w blogu AWS” postu .

Neil
źródło
2

Mam ten sam problem, ale funkcja Lambda, którą implementuję, wstawi wpis w DynamoDB, więc moje rozwiązanie używa wyzwalaczy DynamoDB.

Sprawiam, że DB wywołuje funkcję Lambda dla każdej wstawki / aktualizacji w tabeli, więc oddziela to implementację dwóch funkcji Lambda.

Dokumentacja jest dostępna tutaj: http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Streams.Lambda.html

Oto przewodnik: https://aws.amazon.com/blogs/aws/dynamodb-update-triggers-streams-lambda-cross-region-replication-app/

Lewen
źródło
1

Coś w rodzaju ronda, ale po prostu nazywam punkt końcowy API dla moich funkcji lambda, kiedy muszę je połączyć . Pozwala to zdecydować podczas kodowania, czy mają być asynchroniczne, czy nie.

W przypadku, gdy nie chcesz konfigurować żądania POST, możesz po prostu ustawić proste żądanie GET z kilkoma parametrami zapytania lub wcale, aby ułatwić przekazywanie zdarzeń.

-- Edytować --

Zobacz: https://docs.aws.amazon.com/apigateway/api-reference/making-http-requests/

i: http://docs.aws.amazon.com/lambda/latest/dg/with-on-demand-https-example.html

Anselm
źródło
1
wydaje się to o wiele mniej ronda niż SNS, ale wtedy nie mam dużego doświadczenia w korzystaniu z SNS
Brandon
Czy możesz udostępnić kod potrzebny do wywołania punktu końcowego API z poziomu lambda?
Glenn,
@Glenn to tylko prośba ajax. Oznacz swoje parametry jako parametry zapytania. Zobacz: docs.aws.amazon.com/apigateway/api-reference/… i docs.aws.amazon.com/lambda/latest/dg/…
Anselm
4
Innym problemem jest to, że przejście przez API Gateway jest stosunkowo drogie w porównaniu do wywołania innej funkcji Lambda. Funkcja 128 MB działająca przez 100 ms (minimum) kosztuje 0,21 USD za 1 milion połączeń, a API Gateway kosztuje 3,50 USD za 1 milion. Oczywiście, jeśli biegniesz dłużej lub używasz więcej pamięci RAM, będziesz musiał pomnożyć 21 centów, ale nadal 3,50 USD za milion jest naprawdę drogie. (Ceny obowiązują od sierpnia 2017 r.)
Patrick Chu
1

Inni wskazali na użycie SQS i funkcji krokowych. Ale oba te rozwiązania powodują dodatkowe koszty. Przejścia stanu funkcji kroku są podobno bardzo drogie.

AWS lambda oferuje pewną logikę ponownych prób. Gdzie próbuje coś 3 razy. Nie jestem pewien, czy to nadal jest ważne po uruchomieniu go użyj interfejsu API.

nnrales
źródło
0

Oto przykład pythonowy wywołania innej funkcji lambda i otrzymuje odpowiedź. Istnieją dwa typy wywołań „RequestResponse” i „Event” . Użyj „RequestResponse”, jeśli chcesz uzyskać odpowiedź funkcji lambda, i „Event”, aby wywołać funkcję lambda asynchronicznie. Dostępne są więc oba sposoby asynchroniczny i synchroniczny.

    lambda_response = lambda_client.invoke(
                FunctionName = lambda_name,
                InvocationType = 'RequestResponse',
                Payload = json.dumps(input)
                )
    resp_str = lambda_response['Payload'].read()
    response = json.loads(resp_str)
lalit gangwar
źródło
-1

Możesz ustawić środowisko AWS_REGION.

assert(process.env.AWS_REGION, 'Missing AWS_REGION env (eg. ap-northeast-1)');
const aws = require('aws-sdk');
const lambda = new aws.Lambda();
Hojin
źródło