Чи може функція AWS Lambda викликати іншу


320

У мене є 2 функції лямбда - одна, яка виробляє цитату, і одна, яка перетворює цитату в замовлення. Я хотів би, щоб функція Order lambda викликала функцію Quote, щоб відновити цитату, а не просто отримувати її від недовіреного клієнта.

Я дивився всюди, про що можу придумати - але не бачу, як би я зайнявся ланцюжком або викликом функцій ... напевно, це існує!


1
Я досягаю тут, але чому ви не могли залежати від AWS JavaScript SDK у першій функції Lambda, створити клієнт AWS.Lambda та викликати другу функцію?
devonlazarus

Це те, що я збирався спробувати, але я не був повністю впевнений, як це зробити, так як не було жодних прикладів того, щоб це зробити з іншої функції лямбда.
Срібло

1
мабуть, ви також можете викликати функцію лямбда через HTTP .
devonlazarus

4
і ще одна ідея, ви могли б ланцюг їх через SNS , це, мабуть, шлях, який я б пішов як більш масштабована стратегія
devonlazarus

6
Ще одні поширені альтернативи, про які тут не йдеться, - крокові функції або SWF.
лібріант

Відповіді:


365

Я знайшов спосіб за допомогою 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)
  }
});

Ви можете знайти документа тут: http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/Lambda.html


28
Використання SNS - це, мабуть, кращий підхід, але це правильна відповідь.
Срібло

29
я можу помилятися, але я думаю, оскільки виклик синхронний, що перша лямбда чекає, коли друга лямбда закінчиться, таким чином ви будете нараховувати плату, поки обидва лямбда працюють. використовуючи SNS, перша лямбда повинна припинятися і дозволяти другій лямбда виконувати самостійно.
дев

81
Мені вдалося змусити це працювати завдяки InvocationType: 'Event'параметру (додати його після FunctionNameта Payload). З документів: "Ви можете необов'язково вимагати асинхронного виконання, вказавши подію як тип виклику." При виконанні функції асинхронізації функція зворотного виклику буде надійно викликана, але без необхідності чекати, коли викликана лямбда закінчить виконання.
Алессандро

25
Зауважте, що роль функції виклику лямбда повинна включати політику IAM AWSLambdaRole. Або ви можете додати до існуючої політики вашої ролі наступний об’єкт заяви: '{"Ефект": "Дозволити", "Дія": ["лямбда: InvokeFunction"], "Ресурс": ["*"]} `
Боб Арлоф

4
Насправді AWS випустив StepFunctions, який дозволяє викликати кілька лямбда без необхідності викликати лямбда від іншої лямбда, так що для, тобто. перший не "чекає", коли другий закінчить
Себастьян Х.

116

Ви повинні зав'язати свою мережу Lambda functionsvia SNS. Такий підхід забезпечує хорошу продуктивність, затримку та масштабованість за мінімальні зусилля.

Перше Lambdaпублікує повідомлення вашому, SNS Topicа друге Lambdaпідписане на цю тему. Як тільки повідомлення надходять у тему, друге Lambdaвиконується разом із повідомленням у якості вхідного параметра.

Див. Розділ " Виклик функцій лямбда", використовуючи сповіщення Amazon SNS .

Ви також можете використовувати такий підхід для функціонування Lambda на багаторазовому рахунку через SNS .


2
Кінези можуть бути трохи складнішими, але якщо ви дивитесь на більш надійне рішення, то це може бути для вас хорошим варіантом. Крім того, SNS не зберігає вхідні події, як це робить Kinesis.
kixorz

7
"Ви повинні зв'язати свої функції Lambda через SNS" - чи можете ви підтримати це доказами / посиланнями на документи? Я бачу, як працюватимуть обидва методи, мені було б цікаво побачити деякі думки / певні твердження, щодо яких кращий
Клод

30
Це гарна ідея, якщо вам потрібно, щоб вона була асинхронною. Але якщо вашій першій лямбда-функції потрібне повернене значення з другого лямбда, вам доведеться ланцюг лямбда і перша функція лямбда викликає другу функцію лямбда безпосередньо.
Ноель Ллеварес

3
Я б не рекомендував використовувати SNS. Ви можете просто використовувати API асинхронного виклику для функції лямбда - немає причин використовувати SNS, якщо ви не хочете сповіщати декількох абонентів, а не просто запускати ще одну функцію лямбда.

6
Майте на увазі, що SNS не має гарантії доставки, тому ви можете надіслати повідомлення, але воно може не надійти.
Барт Ван Ремортеле

79

ось зразок коду для python,

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)

До речі, вам потрібно буде додати таку політику до своєї лямбда-ролі

   {
        "Sid": "Stmt1234567890",
        "Effect": "Allow",
        "Action": [
            "lambda:InvokeFunction"
        ],
        "Resource": "*"
    }

Здається, що документація передбачає, що корисне навантаження має бути JSON. Чи можливо надсилати двійкові дані?
mbatchkarov

2
Я також віддаю перевагу цьому методу, але у нього є один глюк. Вам потрібно буде конвертувати datetime.now()рядок (або якось обробити його). В іншому випадку ви отримаєте помилкуdatetime.datetime(2017, 9, 11, 14, 40, 53, 23834) is not JSON serializable
Джон C

Чи можна бути більш обмежуючим у ролі першої лямбда? Тобто, пов'язати це із закликом до певних функцій, а не будь-яких і всіх?
Філ

@Phil, можливо, поле "Ресурс" може бути встановлено таким чином, щоб він мав доступ лише до певного набору функцій, хоча я не зовсім впевнений
blueskin

2
InvocationTypeПовинно бути: RequestResponse. Щоб отримати відповідь від лямбда, яку ви намагаєтеся викликати.
ambigus9

31

Оскільки це запитання було задано, Amazon випустив Step Functions ( https://aws.amazon.com/step-functions/ ).

Одним з основних принципів AWS Lambda є те, що ви можете більше зосередитись на бізнес-логіці та менше на логіці програми, яка пов’язує її разом. Етапні функції дозволяють організувати складні взаємодії між функціями, не потребуючи написання коду для цього.


12

Це рішення виконується за допомогою boto3 та 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

2
InvocationType Виберіть один із наведених нижче варіантів. RequestResponse (за замовчуванням) - викликати функцію синхронно. Тримайте з'єднання відкритим, поки функція не поверне відповідь або не вимкне час. Подія - викликати функцію асинхронно. Надсилайте події, які кілька разів виходять з ладу, у чергу мертвої літери функції (якщо вона налаштована). DryRun - перевірити значення параметрів і переконатися, що користувач або роль мають дозвіл на виклик функції.
Трилок Нагвенкар

11

Я дивився на вирізання SNS, поки не побачив цього в клієнтських документах Lambda (версія Java) :

Клієнт доступу до AWS Lambda. Усі дзвінки служби, здійснені за допомогою цього клієнта, блокуються, і вони не повернуться до завершення службового дзвінка.

Отже, SNS має очевидну перевагу: це асинхронність. Ваша лямбда не чекатиме завершення наступної лямбда.


17
InvocationType = 'Подія' робить його асинхронним. docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/…
Ankit

3
@Ankit, якою має бути обрана відповідь, мене ввели в оману, щоб використовувати SNS єдиний спосіб зробити асинхронний виклик, оскільки ніхто не відповідав цією інформацією.

@Ankit чи знаєте ви приклад, який використовує InvocationType = 'Подія', але з Java замість JavaScript? Є багато документації на Java, але не майже стільки прикладів, як JavaScript
Talador12

SNS все ще додає витрат на його використання
Себастьєн Х.

1
@SebastienH. Для SNS, що посилається на Lambda, немає витрат. aws.amazon.com/sns/pricing
fabdouglas

8

Amazon ввів функції кроків у лямбда AWS у 2016 році. Я думаю, зараз зручніше використовувати функції кроків, оскільки користуватися ними дійсно просто. Можна створити державну машину з двома лямбда-функціями як:

  • виробляти цитату
  • перетворює цитату в замовлення

Ви можете легко зробити це, як показано нижче:

Тут ви можете мати перше стан для створення цитати, а інше - на порядок

{
  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
    }
  }
}

Етапи функції полегшують запис декількох лямбда-функцій та запуск послідовно або паралельно. Ви можете отримати більше інформації про функції лямбда-кроків тут: Етапи функцій


5

Я працював з відповіддю, наданою blueskin, але я не зміг прочитати відповідь Payload, оскільки InvocationType = 'Подія' є асинхронною , тому я змінився як InvocationType = 'RequestResponse', і тепер все працює добре.


5

У Java ми можемо зробити наступне:

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

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

InvokeResult invokeResult = awsLambdaAsync.invoke(invokeRequest); 

Тут корисне навантаження - це ваш стратифікований об’єкт java, який потрібно передати як об’єкт Json в іншу лямбда, якщо вам потрібно передати якусь інформацію від виклику лямбда до називається лямбда.



2

Ви можете закликати функцію лямбда безпосередньо (принаймні через Java), використовуючи, AWSLambdaClientяк описано в публікації блогу AWS .


2

У мене є та сама проблема, але функція Lambda, яку я реалізую, вставить запис у DynamoDB, тому моє рішення використовує тригери DynamoDB.

Я змушую БД викликати функцію Lambda для кожного вставки / оновлення в таблиці, тому це розділяє реалізацію двох функцій Lambda.

Документація представлена ​​тут: http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Streams.Lambda.html

Ось керований посібник: https://aws.amazon.com/blogs/aws/dynamodb-update-triggers-streams-lambda-cross-region-replication-app/


1

Різновид рішення навколо, але я просто називаю кінцеву точку API для моїх лямбда-функцій, коли мені потрібно ланцюг їх. Це дозволяє вам вирішувати під час кодування, хочете ви, щоб вони були асинхронними чи ні.

Якщо ви не хочете налаштувати POST-запит, ви можете просто встановити простий GET-запит з парою або взагалі жодним, запит рядкових параметрів для легкого проходження події.

- Редагувати -

Дивіться: https://docs.aws.amazon.com/apigateway/api-reference/making-http-requests/

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


1
це здається набагато менш крутим, ніж SNS, але тоді я не маю особливого досвіду використання SNS
Брендон

Чи можете ви поділитися кодом, необхідним для виклику кінцевої точки API зсередини лямбда?
Гленн

@Glenn це просто запит на Ajax. Позначте свої параметри, до яких потрібно ввести параметри запиту. Дивіться: docs.aws.amazon.com/apigateway/api-reference/… та docs.aws.amazon.com/lambda/latest/dg/…
Anselm

4
Ще одна проблема полягає в тому, що проходження через шлюз API порівняно дороге порівняно з викликом іншої функції Lambda. Функція 128 Мб, що працює на 100 мс (мінімум), коштує $ 0,21 за 1 мільйон викликів, тоді як API шлюз коштує 3,50 долара за 1 мільйон. Очевидно, що якщо ви бігаєте більше часу або використовуєте більше оперативної пам'яті, вам доведеться помножити 21 цент, але все-таки 3,50 долара на мільйон - це дійсно дорого. (Ці ціни діяли станом на серпень 2017 року)
Патрік Чу

1

Інші вказали на використання функцій SQS та Step. Але обидва ці рішення додають додаткових витрат. Переходи стадійних функцій стану нібито дуже дорогі.

AWS лямбда пропонує деяку логіку повтору. Де щось намагається 3 рази. Я не впевнений, чи це все-таки дійсно, коли ви запускаєте його за допомогою API.


0

Ось приклад python виклику іншої лямбда-функції і отримує її відповідь. Існує два виклики типу "RequestResponse" та "Подія" . Використовуйте "RequestResponse", якщо ви хочете отримати відповідь функції лямбда, і використовуйте "Подія", щоб асинхронно викликати функцію лямбда. Тож доступні обидва способи асинхронного та синхронного.

    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)

-1

Ви можете встановити середовище 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();
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.