ฟังก์ชั่น AWS Lambda สามารถโทรหากันได้หรือไม่


320

ฉันมีฟังก์ชั่นแลมบ์ดา 2 อัน - อันที่ผลิตใบเสนอราคาและอีกอันที่เปลี่ยนใบเสนอราคาเป็นคำสั่ง ฉันต้องการให้ฟังก์ชั่นแลมบ์ดาสั่งซื้อเรียกฟังก์ชั่นอ้างเพื่อสร้างใบเสนอราคาใหม่แทนที่จะได้รับจากลูกค้าที่ไม่น่าเชื่อถือ

ฉันได้ดูทุกที่ที่ฉันนึกถึง - แต่ไม่สามารถดูว่าฉันจะไปเกี่ยวกับการผูกมัดหรือการเรียกใช้ฟังก์ชั่น ... แน่นอนนี้มีอยู่!


1
ฉันมาถึงที่นี่แล้ว แต่ทำไมคุณไม่สามารถพึ่งพา AWS JavaScript SDK ในฟังก์ชั่น Lambda แรกสร้างลูกค้าAWS.Lambdaและเรียกใช้ฟังก์ชันที่สองได้
devonlazarus

มันเป็นสิ่งที่ฉันจะลอง - แต่ฉันก็ไม่แน่ใจว่าจะทำอย่างไรกับมันเนื่องจากไม่มีตัวอย่างของการทำมันจากฟังก์ชั่นแลมบ์ดาอื่น
Silver

1
เห็นได้ชัดว่าคุณสามารถเรียกใช้ฟังก์ชัน Lambda ผ่านHTTPได้
devonlazarus

4
และอีกหนึ่งความคิดคุณสามารถ
โยง

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) จากเอกสาร: "คุณสามารถขอให้ดำเนินการแบบอะซิงโครนัสโดยระบุกิจกรรมเป็น InvocationType" ด้วยการเรียกใช้ async ฟังก์ชันการเรียกกลับจะถูกเรียกอย่างน่าเชื่อถือ แต่ไม่ต้องรอแลมบ์ดาที่เรียกใช้เพื่อดำเนินการให้เสร็จสิ้น
Alessandro

25
AWSLambdaRoleหมายเหตุว่าบทบาทเรียกฟังก์ชั่นของแลมบ์ดาต้องมีนโยบาย IAM หรือคุณสามารถเพิ่มวัตถุคำสั่งต่อไปนี้ในนโยบายที่มีอยู่ของบทบาทของคุณ: '{"Effect": "Allow", "Action": ["lambda: InvokeFunction"], "ทรัพยากร": ["*"]} `
Bob Arlof

4
อันที่จริง AWS เปิดตัว StepFunctions ซึ่งช่วยให้คุณสามารถเรียกแลมบ์ดาหลาย ๆ ตัวได้โดยไม่ต้องเรียกแลมบ์ดาจากแลมบ์ดาอีกตัวหนึ่ง คนแรกไม่ "รอ" เพื่อให้คนที่สองจบ
เซบาสเตียนเอช

116

คุณควรจะห่วงโซ่ของคุณผ่านทางLambda functions SNSวิธีการนี้ให้ประสิทธิภาพที่ดีเวลาในการตอบสนองและความยืดหยุ่นในการใช้งานที่น้อยที่สุด

Lambdaข้อความแรกที่คุณส่งถึงคุณSNS Topicและข้อความที่สองLambdaสมัครรับข้อมูลในหัวข้อนี้ ทันทีที่มีข้อความเข้ามาในหัวข้อข้อความที่สองLambdaจะถูกเรียกใช้งานโดยมีข้อความเป็นพารามิเตอร์อินพุต

ดูฟังก์ชั่นการเรียกใช้การแจ้งเตือนแลมบ์ดา Amazon SNS

นอกจากนี้คุณยังสามารถใช้วิธีนี้เพื่อวิงวอนข้ามบัญชีฟังก์ชั่นแลมบ์ดาผ่านทาง SNS


2
Kinesis อาจซับซ้อนกว่านี้เล็กน้อย แต่ถ้าคุณกำลังมองหาวิธีแก้ปัญหาที่มีประสิทธิภาพมากกว่านี้ก็อาจเป็นตัวเลือกที่ดีสำหรับคุณ นอกจากนี้ SNS ไม่ได้จัดเก็บเหตุการณ์ที่เข้ามา Kinesis ทำ
kixorz

7
"คุณควรเชื่อมโยงฟังก์ชั่นแลมบ์ดาของคุณผ่าน SNS" - คุณสามารถสนับสนุนสิ่งนี้กับหลักฐาน / ลิงค์ไปยังเอกสารได้หรือไม่? ฉันเห็นว่าทั้งสองวิธีทำงานอย่างไรฉันสนใจที่จะเห็นความคิดเห็น / ข้อความที่ชัดเจนว่าเป็นวิธีใดที่เป็นที่ต้องการ
Claude

30
นี่เป็นความคิดที่ดีถ้าคุณต้องการแบบอะซิงโครนัส แต่ถ้าฟังก์ชั่นแลมบ์ดาแรกของคุณต้องการค่าส่งคืนจากแลมบ์ดาที่สองคุณต้องโยงแลมบ์ดาและมีฟังก์ชั่นแลมบ์ดาแรกเรียกใช้ฟังก์ชันแลมบ์ดาที่สองโดยตรง
Noel Llevares

3
ฉันจะไม่แนะนำให้ใช้ SNS คุณสามารถใช้ API การเรียกใช้แบบอะซิงโครนัสสำหรับฟังก์ชั่น lambda ได้โดยไม่มีเหตุผลใดที่จะใช้ SNS เว้นแต่คุณต้องการแจ้งเตือนสมาชิกหลายรายและไม่เพียงแค่เรียกใช้ฟังก์ชัน lambda อื่น

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": "*"
    }

เอกสารดูเหมือนว่าจะแนะนำ payload ต้องเป็น JSON เป็นไปได้ไหมที่จะส่งข้อมูลไบนารี
mbatchkarov

2
ฉันชอบวิธีนี้เช่นกัน แต่มันมีความผิดพลาดเพียงอย่างเดียว คุณจะต้องแปลงdatetime.now()เป็นสตริง (หรือจัดการมันอย่างใด) มิฉะนั้นคุณจะได้รับข้อผิดพลาดdatetime.datetime(2017, 9, 11, 14, 40, 53, 23834) is not JSON serializable
John C

เป็นไปได้ไหมที่จะมีข้อ จำกัด ในบทบาทของแลมบ์ดาแรก? คือเพื่อผูกมันลงเพื่อกล่าวอ้างฟังก์ชั่นที่เฉพาะเจาะจงมากกว่าหรือไม่?
Phil

@ ฟิลอาจจะตั้งค่าฟิลด์ "ทรัพยากร" เพื่ออนุญาตเฉพาะชุดฟังก์ชั่นที่เฉพาะเจาะจงฉันไม่แน่ใจว่าสมบูรณ์
blueskin

2
ควรจะ:InvocationType RequestResponseเพื่อรับการตอบสนองจากแลมบ์ดาที่คุณพยายามเรียกใช้
ambigus9

31

ตั้งแต่มีการถามคำถามนี้ Amazon ได้เปิดตัวฟังก์ชั่นขั้นตอน ( 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 (ค่าเริ่มต้น) - เรียกใช้ฟังก์ชันพร้อมกัน เปิดการเชื่อมต่อค้างไว้จนกว่าฟังก์ชันจะตอบกลับหรือหมดเวลา เหตุการณ์ - เรียกใช้ฟังก์ชันแบบอะซิงโครนัส ส่งเหตุการณ์ที่ล้มเหลวหลายครั้งไปยังคิว dead-letter ของฟังก์ชัน (หากกำหนดค่า) DryRun - ตรวจสอบค่าพารามิเตอร์และตรวจสอบว่าผู้ใช้หรือบทบาทได้รับอนุญาตให้เรียกใช้ฟังก์ชัน
Trilok Nagvenkar

11

ฉันกำลังตรวจสอบการตัด SNS ออกจนกว่าฉันจะเห็นสิ่งนี้ในเอกสารลูกค้าของแลมบ์ดา (เวอร์ชั่น Java) :

ไคลเอนต์สำหรับการเข้าถึง AWS Lambda การเรียกใช้บริการทั้งหมดที่ทำโดยใช้ไคลเอ็นต์นี้กำลังปิดกั้นและจะไม่ส่งคืนจนกว่าการเรียกใช้บริการจะเสร็จสิ้น

ดังนั้น SNS จึงมีข้อได้เปรียบที่เห็นได้ชัด: เป็นแบบอะซิงโครนัส แลมบ์ดาของคุณจะไม่รอให้แลมบ์ดานั้นเสร็จสมบูรณ์


17
InvocationType = 'Event' ทำให้เป็น async docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/…
Ankit

3
@ Kit ที่ควรเป็นคำตอบที่เลือกฉันเข้าใจผิดว่าการใช้ SNS เป็นวิธีเดียวที่จะทำการเรียกใช้แบบอะซิงโครนัสได้เนื่องจากไม่มีใครตอบข้อมูลนี้

@Ankit คุณรู้จักตัวอย่างโดยใช้ InvocationType = 'Event' แต่มาจาก Java แทนที่จะเป็น JavaScript? มีเอกสาร Java จำนวนมาก แต่มีตัวอย่างไม่มากเท่า JavaScript
Talador12

SNS ยังคงเพิ่มค่าใช้จ่ายสำหรับการใช้งาน
เซบาสเตียนเอช

1
@SebastienH ไม่มีค่าใช้จ่ายสำหรับ SNS ที่เรียกใช้ Lambda aws.amazon.com/sns/pricing
fabdouglas

8

Amazon ได้เปิดตัวฟังก์ชั่นขั้นตอนใน AWS แลมบ์ดาในปี 2559 ฉันคิดว่าตอนนี้มันสะดวกกว่าที่จะใช้ฟังก์ชั่นขั้นตอนเพราะมันใช้งานง่ายมาก คุณสามารถสร้างเครื่องรัฐที่มีฟังก์ชั่นแลมบ์ดาสองฟังก์ชั่นดังนี้

  • เพื่อผลิตใบเสนอราคา
  • เปลี่ยนคำพูดเป็นคำสั่ง

คุณสามารถทำสิ่งต่อไปนี้ได้อย่างง่ายดาย:

ที่นี่คุณสามารถมีสถานะแรกสำหรับผลิตใบเสนอราคาและอีกใบเพื่อเปลี่ยนเป็นคำสั่ง

{
  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 response ได้เพราะInvocationType = 'Event'เป็นasyncดังนั้นฉันจึงเปลี่ยนเป็น 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); 

ที่นี่น้ำหนักบรรทุกเป็นวัตถุ java ของคุณstringifiedซึ่งจะต้องมีการส่งผ่านเป็นวัตถุ Json ไปแลมบ์ดาอื่นในกรณีที่คุณต้องผ่านข้อมูลบางส่วนจากการเรียกแลมบ์ดาที่จะเรียกว่าแลมบ์ดา



2

คุณสามารถเรียกฟังก์ชั่นแลมบ์ดาโดยตรง (อย่างน้อยผ่าน Java) โดยใช้AWSLambdaClientตามที่อธิบายไว้ในบล็อก AWS' โพสต์


2

ฉันมีปัญหาเดียวกัน แต่ฟังก์ชั่นแลมบ์ดาที่ฉันใช้จะแทรกรายการใน DynamoDB ดังนั้นโซลูชันของฉันจึงใช้ DynamoDB Triggers

ฉันทำให้ DB เรียกใช้ฟังก์ชันแลมบ์ดาสำหรับทุกส่วนแทรก / อัพเดตในตารางดังนั้นสิ่งนี้จะแยกการใช้งานของฟังก์ชั่นแลมบ์ดาทั้งสอง

เอกสารอยู่ที่นี่: 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-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 Gateway นั้นค่อนข้างแพงเมื่อเทียบกับการเรียกใช้ฟังก์ชัน Lambda อื่น ฟังก์ชั่น 128MB ใช้งานได้ 100 มิลลิวินาที (ขั้นต่ำ) ค่าใช้จ่าย $ 0.21 ต่อการโทร 1 ล้านครั้งในขณะที่ API Gateway มีค่าใช้จ่าย $ 3.50 ต่อ 1 ล้าน เห็นได้ชัดว่าถ้าคุณใช้เวลามากขึ้นหรือคุณใช้ RAM เพิ่มขึ้นคุณจะต้องคูณ 21 เซนต์ แต่ก็ยังคงมีราคา $ 3.50 ต่อล้านนั้นแพงจริงๆ (ราคานี้มีผลบังคับใช้ตั้งแต่เดือนสิงหาคม 2017)
Patrick Chu

1

คนอื่น ๆ ชี้ให้เห็นถึงการใช้ SQS และฟังก์ชั่นขั้นตอน แต่โซลูชั่นทั้งสองนี้มีค่าใช้จ่ายเพิ่มเติม ขั้นตอนการเปลี่ยนสถานะฟังก์ชันมีค่าใช้จ่ายสูงมาก

แลมบ์ดา AWS เสนอตรรกะลองใหม่บางอย่าง มันพยายามทำอะไรซักอย่าง 3 ครั้ง ฉันไม่แน่ใจว่ายังใช้งานได้หรือไม่เมื่อคุณทริกเกอร์ใช้ API


0

นี่คือตัวอย่างของการเรียกฟังก์ชั่นแลมบ์ดาและรับการตอบกลับของมัน มีสองประเภทคือการภาวนา'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();
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.