AWS Lambda 함수가 다른 함수를 호출 할 수 있습니까


320

2 개의 Lambda 함수가 있습니다-하나는 견적을 생성하고 하나는 견적을 주문으로 바꿉니다. Order lambda 함수가 신뢰할 수없는 클라이언트로부터 견적을받는 것이 아니라 견적 함수를 호출하여 견적을 재생성하고 싶습니다.

나는 내가 생각할 수있는 모든 곳을 보았지만 함수를 연결하거나 호출하는 방법을 볼 수는 없습니다 ... 확실히 이것이 존재합니다!


1
여기에 도달했지만 첫 번째 Lambda 함수에서 AWS JavaScript SDK를 사용하여 AWS.Lambda 클라이언트를 생성 하고 두 번째 함수를 호출 할 수없는 이유는 무엇입니까?
devonlazarus

그것은 시도하려고하는 것입니다. 그러나 다른 Lambda 함수에서 수행하는 예가 없었기 때문에 어떻게 해야할지 완전히 확신하지 못했습니다.
Silver

1
분명히 HTTP를 통해 Lambda 함수를 호출 할 수도 있습니다 .
devonlazarus

4
그리고 하나 더 생각하면, 당신은 SNS를 통해 그것들을 연결시킬있습니다 . 이것은 아마도 더 확장 가능한 전략으로 갈 것입니다
devonlazarus

6
여기에 언급되지 않은 또 다른 일반적인 대안은 단계 함수 또는 SWF입니다.
lebryant

답변:


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를 사용하면 첫 번째 람다는 종료되고 두 번째 람다는 독립적으로 실행될 수 있어야합니다.
dev

81
InvocationType: 'Event'매개 변수 덕분 에이 작업을 수행 할 수있었습니다 ( FunctionName및 뒤에 추가하십시오 Payload). 문서에서 : "선택적으로 Event를 InvocationType으로 지정하여 비동기 실행을 요청할 수 있습니다." 비동기 실행을 사용하면 콜백 함수가 안정적으로 호출되지만 호출 된 람다는 실행이 끝날 때까지 기다릴 필요가 없습니다.
Alessandro

25
호출하는 람다 함수의 역할에는 IAM 정책이 포함되어야 AWSLambdaRole합니다. 또는 역할의 기존 정책에 다음 명령문 오브젝트를 추가 할 수 있습니다. '{ "Effect": "Allow", "Action": [ "lambda : InvokeFunction"], "Resource": [ "*"]}`
Bob Arlof의

4
실제로 AWS는 다른 람다에서 람다를 호출하지 않고도 여러 람다를 호출 할 수있는 StepFunctions를 출시했습니다. 첫 번째는 두 번째가
Sebastien H.

116

Lambda functions를 통해 체인을 연결해야합니다 SNS. 이 접근 방식은 최소한의 노력으로 우수한 성능, 대기 시간 및 확장 성을 제공합니다.

첫 번째 는 Lambda귀하에게 메시지를 게시 SNS Topic하고 두 번째 Lambda는이 주제를 구독합니다. 메시지가 주제에 도착하자마자 두 번째 Lambda는 메시지를 입력 매개 변수로 사용하여 실행됩니다.

Amazon SNS 알림을 사용하여 Lambda 함수 호출을 참조하십시오 .

이 접근 방식을 사용 하여 SNS를 통해 교차 계정 Lambda 함수를 호출 할 수도 있습니다 .


2
Kinesis는 좀 더 복잡 할 수 있지만보다 강력한 솔루션을 찾고 있다면 좋은 선택 일 수 있습니다. 또한 SNS는 들어오는 이벤트를 저장하지 않고 Kinesis는 저장합니다.
kixorz 2016 년

7
"SNS를 통해 Lambda 함수를 연결해야합니다"-문서에 대한 증거 / 링크로이를 지원할 수 있습니까? 두 방법이 어떻게 작동하는지 봅니다. 선호하는 의견이나 명확한 진술을 보는 데 관심이 있습니다
Claude

30
비동기식이 필요한 경우에 좋습니다. 그러나 첫 번째 람다 함수 두 번째 람다에서 반환 된 값이 필요한 경우 람다를 연결하고 첫 번째 람다 함수가 두 번째 람다 함수를 직접 호출해야합니다.
Noel Llevares

3
SNS를 사용하지 않는 것이 좋습니다. 여러 구독자에게 알리고 다른 람다 함수 만 트리거하지 않는 한 SNS를 사용하는 이유없이 람다 함수에 비동기 호출 API를 사용할 수 있습니다.

6
SNS에는 배달 보증이 없으므로 메시지를 보내지 만 도착하지 않을 수 있습니다.
Bart Van Remortele

79

다음은 파이썬 샘플 코드입니다.

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)

Btw, 람다 역할에 이와 같은 정책을 추가해야합니다.

   {
        "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
John C

첫 번째 람다의 역할에서 더 제한적일 수 있습니까? 즉, 특정 기능 을 호출하는 것과 연결하는 것이 무엇입니까?
Phil

@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-매개 변수 값의 유효성을 검증하고 사용자 또는 역할에 기능을 호출 할 권한이 있는지 확인하십시오.
Trilok Nagvenkar

11

Lambda 클라이언트 문서 (Java 버전) 에서 이것을 볼 때까지 SNS를 잘라내는 것을보고있었습니다 .

AWS Lambda에 액세스하기위한 클라이언트 이 클라이언트를 사용하여 이루어진 모든 서비스 호출은 차단되며 서비스 호출이 완료 될 때까지 반환되지 않습니다.

따라서 SNS는 분명한 장점이 있습니다. 그것은 비동기 적입니다. 람다는 후속 람다가 완료되기를 기다리지 않습니다.


17
InvocationType = 'Event'는 비 동기화합니다. docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/…
Ankit

3
@Ankit은 선택된 답변이어야합니다. 아무도이 정보에 응답하지 않았기 때문에 SNS를 사용하는 것이 비동기 호출을 수행하는 유일한 방법이라고 믿었습니다.

@Ankit InvocationType = 'Event'사용하지만 JavaScript 대신 Java의 예제를 알고 있습니까? 많은 Java 문서가 있지만 JavaScript만큼 많은 예제는 없습니다
Talador12

SNS는 여전히 사용 비용을 추가합니다
Sebastien H.

1
@SebastienH. Lambda를 호출하는 SNS에 대한 비용은 없습니다. aws.amazon.com/sns/pricing
fabdouglas

8

아마존은 2016 년에 AWS 람다에 단계 함수를 도입했습니다. 이제는 단계 함수를 사용하는 것이 매우 편리하므로 단계 함수를 사용하는 것이 더 편리하다고 생각합니다. 다음과 같이 두 개의 람다 함수를 사용하여 상태 머신을 빌드 할 수 있습니다.

  • 견적을 생성
  • 견적을 주문으로 변환

아래와 같이 쉽게 할 수 있습니다.

여기에서 견적을 생성하는 첫 번째 상태와 순서로 변환 할 다른 상태를 가질 수 있습니다.

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

Steps 함수를 사용하면 여러 람다 함수를 쉽게 작성하고 순서대로 또는 병렬로 실행할 수 있습니다. 여기 람다 단계 함수에 대한 자세한 정보를 얻을 수 있습니다 : 단계 기능을


5

blueskin에서 제공 한 답변을 사용하고 있었지만 InvocationType = 'Event'async 이므로 Payload 응답을 읽을 수 없으므로 InvocationType = 'RequestResponse'로 변경되어 이제는 모두 잘 작동합니다.


5

자바에서는 다음과 같이 할 수 있습니다.

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

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

InvokeResult invokeResult = awsLambdaAsync.invoke(invokeRequest); 

여기에서 페이로드는 람다 호출에서 호출 된 람다에 대한 정보를 전달 해야하는 경우를 대비하여 Json 객체로 다른 람다에 전달 해야하는 문자열 화 된 Java 객체입니다.



2

AWSLambdaClientAWS 블로그 게시물에 설명 된대로 람다 함수를 직접 (적어도 Java를 통해) 호출 할 수 있습니다 .


2

동일한 문제가 있지만 구현하는 Lambda 함수가 DynamoDB에 항목을 삽입하므로 솔루션에서 DynamoDB 트리거를 사용합니다.

DB가 테이블의 모든 삽입 / 업데이트에 대해 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를 사용한 경험이 많지 않습니다
Brandon

람다 내에서 API 엔드 포인트를 호출하는 데 필요한 코드를 공유 할 수 있습니까?
Glenn

@ 글렌 그것은 단지 아약스 요청입니다. 쿼리 매개 변수로 필요한 매개 변수에 태그를 지정하십시오. 참조 : docs.aws.amazon.com/apigateway/api-reference/…docs.aws.amazon.com/lambda/latest/dg/…
Anselm

4
또 다른 문제는 API 게이트웨이를 통과하는 것이 다른 Lambda 함수를 호출하는 것에 비해 상대적으로 비싸다는 것입니다. 100ms (최소)로 실행되는 128MB 기능은 1 백만 호출 당 0.21 달러이고 API 게이트웨이는 1 백만 당 3.50 달러입니다. 분명히, 당신이 더 많은 시간 동안 달리거나 더 많은 램을 사용한다면, 21 센트를 곱해야하지만, 여전히 백만 당 $ 3.50는 정말 비쌉니다. (이 가격은 2017 년 8 월부터 유효했습니다)
Patrick Chu

1

다른 사람들은 SQS와 Step Functions를 사용한다고 지적했습니다. 그러나이 두 가지 솔루션 모두 추가 비용이 발생합니다. Step Function 상태 전이는 매우 비싸다.

AWS Lambda는 몇 가지 재시도 로직을 제공합니다. 3 번 시도하는 곳. API를 사용하여 트리거 할 때 여전히 유효한지 확실하지 않습니다.


0

다음은 다른 람다 함수를 호출하고 응답을 얻는 파이썬 예제입니다. 'RequestResponse''Event'의 두 가지 호출 유형이 있습니다 . 람다 함수의 응답을 얻으려면 'RequestResponse'를 사용하고 'Event'를 사용하여 람다 함수를 비동기 적으로 호출하십시오. 따라서 비동기 및 동기 방식을 모두 사용할 수 있습니다.

    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();
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.