Hàm AWS Lambda có thể gọi khác không


320

Tôi có 2 chức năng Lambda - một chức năng tạo ra một trích dẫn và một chức năng biến một trích dẫn thành một đơn đặt hàng. Tôi muốn chức năng Order lambda gọi hàm Trích dẫn để tạo lại trích dẫn, thay vì chỉ nhận nó từ một khách hàng không tin cậy.

Tôi đã nhìn mọi nơi tôi có thể nghĩ đến - nhưng không thể thấy tôi sẽ xâu chuỗi hay gọi các chức năng như thế nào ... chắc chắn điều này tồn tại!


1
Tôi đang đến đây, nhưng tại sao bạn không thể phụ thuộc vào SDK JavaScript AWS trong chức năng Lambda đầu tiên, tạo ứng dụng khách AWS.Lambdagọi chức năng thứ hai?
devonlazarus

Đó là những gì tôi sẽ thử - nhưng tôi không hoàn toàn chắc chắn về cách thực hiện, vì không có bất kỳ ví dụ nào về việc thực hiện nó từ một chức năng Lambda khác.
Bạc

1
rõ ràng bạn cũng có thể gọi hàm Lambda thông qua HTTP .
devonlazarus

4
và một ý tưởng nữa, bạn có thể xâu chuỗi chúng thông qua SNS , đó có lẽ là cách tôi sẽ thực hiện như một chiến lược có thể mở rộng hơn
devonlazarus

6
Một lựa chọn thay thế phổ biến khác không được đề cập ở đây là Step Function hoặc SWF.
lebryant

Câu trả lời:


365

Tôi tìm thấy một cách sử dụng 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)
  }
});

Bạn có thể tìm thấy tài liệu ở đây: http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/Lambda.html


28
Sử dụng SNS có lẽ là cách tiếp cận tốt hơn, nhưng đây là câu trả lời chính xác.
Bạc

29
Tôi có thể sai, nhưng tôi nghĩ bởi vì lời cầu khẩn là đồng bộ rằng lambda đầu tiên chờ lambda thứ hai chấm dứt, do đó bạn sẽ tích lũy phí trong khi cả hai lambdas đang chạy. sử dụng SNS, lambda đầu tiên sẽ chấm dứt và cho phép lambda thứ hai thực thi độc lập.
dev

81
Tôi đã có thể làm cho nó hoạt động nhờ vào InvocationType: 'Event'tham số (thêm nó sau FunctionNamePayload). Từ các tài liệu: "Bạn có thể tùy chọn yêu cầu thực thi không đồng bộ bằng cách chỉ định Sự kiện là InvocationType." Với thực thi async, chức năng gọi lại sẽ được gọi một cách đáng tin cậy, nhưng không phải đợi lambda được gọi để thực hiện xong.
Alessandro

25
Lưu ý rằng vai trò của hàm lambda cần bao gồm chính sách IAM AWSLambdaRole. Hoặc, bạn có thể thêm đối tượng câu lệnh sau vào chính sách hiện có của vai trò của mình: '{"Hiệu ứng": "Cho phép", "Hành động": ["lambda: InvokeFunction"], "Tài nguyên": ["*"]} `
Bob Arlof

4
Trên thực tế AWS đã phát hành StepFifts cho phép bạn gọi nhiều lambda mà không cần phải gọi lambda từ lambda khác, vì vậy, ví dụ như vậy. cái đầu tiên không "đợi" cái thứ hai kết thúc
Sebastien H.

116

Bạn nên xâu chuỗi Lambda functionsqua SNS. Cách tiếp cận này cung cấp hiệu suất tốt, độ trễ và khả năng mở rộng cho nỗ lực tối thiểu.

Đầu tiên của bạn Lambdaxuất bản tin nhắn của bạn SNS Topicvà thứ hai Lambdađược đăng ký vào chủ đề này. Ngay khi tin nhắn đến chủ đề, giây Lambdasẽ được thực thi với thông điệp là tham số đầu vào.

Xem Gọi chức năng Lambda bằng thông báo SNS của Amazon .

Bạn cũng có thể sử dụng phương pháp này để gọi các hàm Lambda có tài khoản chéo thông qua SNS .


2
Kinesis có thể phức tạp hơn một chút, nhưng nếu bạn đang tìm kiếm giải pháp mạnh mẽ hơn, thì đó có thể là một lựa chọn tốt cho bạn. Ngoài ra, SNS không lưu trữ các sự kiện đến, Kinesis cũng vậy.
kixorz

7
"Bạn nên xâu chuỗi các chức năng Lambda của mình thông qua SNS" - bạn có thể hỗ trợ điều này với bằng chứng / liên kết đến tài liệu không? Tôi thấy cả hai phương pháp sẽ hoạt động như thế nào, tôi sẽ thích thú khi thấy một số ý kiến ​​/ tuyên bố chắc chắn về cái nào là phương pháp được ưa thích
Claude

30
Đây là một ý tưởng tốt nếu bạn cần nó không đồng bộ. Nhưng nếu hàm lambda đầu tiên của bạn cần giá trị trả về từ lambda thứ hai, bạn phải xâu chuỗi lambdas và có hàm lambda đầu tiên gọi trực tiếp hàm lambda thứ hai.
Noel Llevares

3
Tôi không khuyên bạn nên sử dụng SNS. Bạn chỉ có thể sử dụng API gọi không đồng bộ cho chức năng lambda - không có lý do gì để sử dụng SNS trừ khi bạn muốn thông báo cho nhiều người đăng ký và không chỉ kích hoạt chức năng lambda khác.

6
Hãy nhớ rằng SNS không có bảo đảm chuyển phát nên bạn có thể gửi tin nhắn nhưng nó có thể không đến.
Bart Van Remortele

79

đây là mã mẫu cho 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)

Btw, bạn cũng cần thêm một chính sách như thế này vào vai trò lambda của mình

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

Các tài liệu dường như đề xuất tải trọng phải là JSON. Có thể gửi dữ liệu nhị phân?
mbatchkarov

2
Tôi cũng thích phương pháp này, nhưng nó có một trục trặc. Bạn sẽ cần phải chuyển đổi datetime.now()chuỗi thành một chuỗi (hoặc xử lý nó bằng cách nào đó). Nếu không, bạn sẽ gặp lỗidatetime.datetime(2017, 9, 11, 14, 40, 53, 23834) is not JSON serializable
John C

Có thể hạn chế hơn trong vai trò của lambda đầu tiên không? Tức là, để buộc nó xuống để gọi các chức năng cụ thể , chứ không phải bất kỳ và tất cả?
Phil

@Phil có thể trường "Tài nguyên" có thể được đặt để chỉ cho phép một bộ chức năng cụ thể, tuy nhiên tôi không hoàn toàn chắc chắn
blueskin

2
Các InvocationTypenên: RequestResponse. Để nhận được phản hồi từ lambda mà bạn đang cố gắng gọi.
ambigus9

31

Vì câu hỏi này đã được hỏi, Amazon đã phát hành Step Function ( https://aws.amazon.com/step-fifts/ ).

Một trong những nguyên tắc cốt lõi đằng sau AWS Lambda là bạn có thể tập trung nhiều hơn vào logic kinh doanh và ít hơn vào logic ứng dụng gắn kết tất cả lại với nhau. Các hàm bước cho phép bạn phối hợp các tương tác phức tạp giữa các hàm mà không phải viết mã để thực hiện.


12

Giải pháp này được thực hiện bằng boto3 và 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 Chọn từ các tùy chọn sau. RequestResponse (mặc định) - Gọi hàm đồng bộ. Giữ kết nối mở cho đến khi chức năng trả về phản hồi hoặc hết thời gian. Sự kiện - Gọi hàm không đồng bộ. Gửi các sự kiện thất bại nhiều lần đến hàng đợi chữ cái chết của hàm (nếu được định cấu hình). DryRun - Xác thực các giá trị tham số và xác minh rằng người dùng hoặc vai trò có quyền gọi hàm.
Trilok Nagvenkar

11

Tôi đã xem xét cắt bỏ SNS cho đến khi tôi thấy điều này trong tài liệu máy khách Lambda (phiên bản Java) :

Khách hàng truy cập AWS Lambda. Tất cả các cuộc gọi dịch vụ được thực hiện bằng ứng dụng khách này đều bị chặn và sẽ không trả lại cho đến khi cuộc gọi dịch vụ hoàn tất.

Vì vậy, SNS có một lợi thế rõ ràng: đó là không đồng bộ. Lambda của bạn sẽ không chờ lambda tiếp theo hoàn thành.


17
InvocationType = 'Event' làm cho nó không đồng bộ. docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/iêu
Ankit

3
@Ankit nên là câu trả lời được chọn, tôi đã lầm tưởng rằng sử dụng SNS là cách duy nhất để thực hiện một yêu cầu không đồng bộ vì không ai trả lời với thông tin này.

@Ankit bạn có biết một ví dụ sử dụng InvocationType = 'Event' nhưng từ Java thay vì JavaScript không? Có rất nhiều tài liệu Java, nhưng gần như không có nhiều ví dụ như JavaScript
Talador12

SNS vẫn thêm chi phí cho việc sử dụng
Sebastien H.

1
@SebastienH. Không có chi phí cho SNS gọi Lambda. aws.amazon.com/sns/pricing
fabdoumund

8

Amazon đã giới thiệu các bước chức năng trong AWS lambda vào năm 2016. Tôi nghĩ, giờ đây việc sử dụng chức năng các bước sẽ thuận tiện hơn vì nó thực sự dễ sử dụng. Bạn có thể xây dựng một máy trạng thái với hai chức năng lambda là:

  • để tạo ra một trích dẫn
  • biến một trích dẫn thành một đơn đặt hàng

Bạn có thể dễ dàng làm điều đó như dưới đây:

Ở đây bạn có thể có trạng thái đầu tiên để tạo ra một trích dẫn và trạng thái khác để biến thành thứ tự

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

Các bước chức năng làm cho nó thực sự dễ dàng để viết nhiều hàm lambda và chạy theo trình tự hoặc song song. Bạn có thể nhận thêm thông tin về các chức năng bước lambda tại đây: Các bước chức năng


5

Tôi đã làm việc với các câu trả lời được cung cấp bởi blueskin nhưng tôi không thể đọc những phản ứng Payload vì InvocationType = 'sự kiện'async , vì vậy tôi đã thay đổi như InvocationType = 'RequestResponse' và bây giờ tất cả hoạt động tốt.


5

Trong java, chúng ta có thể làm như sau:

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

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

InvokeResult invokeResult = awsLambdaAsync.invoke(invokeRequest); 

Ở đây, tải trọng là đối tượng java được xâu chuỗi của bạn cần được chuyển dưới dạng đối tượng Json sang một lambda khác trong trường hợp bạn cần chuyển một số thông tin từ việc gọi lambda sang gọi lambda.



2

Bạn có thể gọi hàm lambda trực tiếp (ít nhất là qua Java) bằng cách sử dụng AWSLambdaClientnhư được mô tả trong bài đăng trên blog của AWS .


2

Tôi đang gặp vấn đề tương tự nhưng chức năng Lambda mà tôi triển khai sẽ chèn một mục trong DynamoDB, vì vậy giải pháp của tôi sử dụng Trình kích hoạt DynamoDB.

Tôi tạo DB gọi hàm Lambda cho mỗi lần chèn / cập nhật trong bảng, vì vậy điều này phân tách việc thực hiện hai hàm Lambda.

Tài liệu có tại đây: http://docs.aws.amazon.com/amazondoperodb/latest/developerguide/Streams.Lambda.html

Dưới đây là hướng dẫn được hướng dẫn: https://aws.amazon.com/bloss/aws/dynamodb-update-triggers-streams-lambda-cross-region-replication-app/


1

Một loại giải pháp bùng binh nhưng tôi chỉ gọi điểm cuối API cho các hàm lambda của mình khi tôi cần xâu chuỗi chúng. Điều này cho phép bạn quyết định trong khi mã hóa nếu bạn muốn chúng không đồng bộ hay không.

Trong trường hợp bạn không muốn thiết lập một yêu cầu POST, bạn chỉ có thể thiết lập một yêu cầu GET đơn giản với một vài hoặc không có gì cả, các tham số chuỗi truy vấn để dễ dàng vượt qua.

-- Biên tập --

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

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


1
điều này có vẻ ít vòng xoay hơn SNS, nhưng sau đó tôi không có nhiều kinh nghiệm sử dụng SNS
Brandon

Bạn có thể chia sẻ mã cần thiết để gọi điểm cuối API từ bên trong lambda không?
Glenn

@Glenn nó chỉ là một yêu cầu ajax. Tag vào các tham số của bạn mà bạn cần làm tham số truy vấn. Xem: docs.aws.amazon.com/apigateway/api-reference/ trêndocs.aws.amazon.com/lambda/latest/dg/ trộm
Anselm

4
Một vấn đề khác là việc đi qua API Gateway tương đối tốn kém so với việc gọi một hàm Lambda khác. Hàm 128 MB chạy trong 100ms (tối thiểu) có giá 0,21 đô la cho 1 triệu cuộc gọi, trong khi API Gateway có giá 3,50 đô la cho mỗi 1 triệu. Rõ ràng, nếu bạn đang chạy nhiều thời gian hơn hoặc bạn sử dụng nhiều ram hơn, bạn sẽ phải nhân 21 xu, nhưng vẫn có, 3,50 đô la mỗi triệu là thực sự tốn kém. (Giá này có hiệu lực kể từ tháng 8 năm 2017)
Patrick Chu

1

Những người khác chỉ ra để sử dụng hàm SQS và Step. Nhưng cả hai giải pháp này đều thêm chi phí. Bước chuyển trạng thái chức năng được cho là rất tốn kém.

AWS lambda cung cấp một số logic thử lại. Nơi nó cố gắng một cái gì đó trong 3 lần. Tôi không chắc liệu điều đó có còn hiệu lực hay không khi bạn kích hoạt nó sử dụng API.


0

Dưới đây là ví dụ python về việc gọi một hàm lambda khác và nhận được phản hồi của nó. Có hai loại yêu cầu 'RequestResponse''Event' . Sử dụng 'RequestResponse' nếu bạn muốn nhận được phản hồi của hàm lambda và sử dụng 'Sự kiện' để gọi hàm lambda không đồng bộ. Vì vậy, cả hai cách không đồng bộ và đồng bộ đều có sẵn.

    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

Bạn có thể đặt môi trường 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();
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.