Dapatkah fungsi AWS Lambda memanggil yang lain

320

Saya memiliki 2 fungsi Lambda - yang menghasilkan penawaran dan yang mengubah penawaran menjadi pesanan. Saya ingin fungsi Order lambda untuk memanggil fungsi Penawaran untuk membuat ulang penawaran, daripada hanya menerimanya dari klien yang tidak terpercaya.

Saya telah mencari di mana-mana yang dapat saya pikirkan - tetapi tidak dapat melihat bagaimana saya akan melakukan chaining atau memanggil fungsi ... pasti ini ada!

Perak
sumber
1
Saya sampai di sini, tetapi mengapa Anda tidak dapat bergantung pada AWS JavaScript SDK di fungsi Lambda pertama, membuat klien AWS.Lambda dan menjalankan fungsi kedua?
devonlazarus
Itu yang akan saya coba - tetapi saya tidak sepenuhnya yakin bagaimana cara melakukannya, karena tidak ada contoh melakukannya dari fungsi Lambda lain.
Perak
1
ternyata Anda juga dapat menjalankan fungsi Lambda melalui HTTP .
devonlazarus
4
dan satu ide lagi, Anda dapat memadukan mereka melalui SNS , yang mungkin merupakan cara saya akan menjadi strategi yang lebih skalabel
devonlazarus
6
Alternatif umum lainnya yang tidak disebutkan di sini adalah Fungsi Langkah atau SWF.
lebryant

Jawaban:

365

Saya menemukan cara menggunakan 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)
  }
});

Anda dapat menemukan dokumen di sini: http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/Lambda.html

Nicolas Grenié
sumber
28
Menggunakan SNS mungkin merupakan pendekatan yang lebih baik, tetapi ini adalah jawaban yang benar.
Perak
29
saya bisa saja salah, tapi saya pikir karena doa serempak bahwa lambda pertama menunggu lambda kedua berakhir, maka Anda akan dikenakan biaya saat kedua lambda berjalan. menggunakan SNS, lambda pertama harus berakhir dan memungkinkan lambda kedua dieksekusi secara independen.
dev
81
Saya bisa mendapatkan ini berfungsi berkat InvocationType: 'Event'parameter (tambahkan setelah FunctionNamedan Payload). Dari dokumen: "Anda dapat secara opsional meminta eksekusi asinkron dengan menentukan Peristiwa sebagai Jenis Invokasi." Dengan eksekusi async, fungsi callback akan dipanggil dengan andal, tetapi tanpa harus menunggu lambda yang dipanggil untuk menyelesaikan eksekusi.
Alessandro
25
Perhatikan bahwa peran fungsi lambda perlu memasukkan kebijakan IAM AWSLambdaRole. Atau, Anda dapat menambahkan objek pernyataan berikut ke kebijakan peran Anda yang ada: '{"Effect": "Allow", "Action": ["lambda: InvokeFunction"], "Resource": ["*"]} `
Bob Arlof
4
Sebenarnya AWS merilis StepFunctions yang memungkinkan Anda untuk memanggil beberapa lambda tanpa harus Meminta lambda dari lambda lain, jadi untuk itu. yang pertama tidak "menunggu" sampai yang kedua selesai
Sebastien H.
116

Anda harus rantai Lambda functionsvia AndaSNS . Pendekatan ini memberikan kinerja yang baik, latensi, dan skalabilitas untuk upaya minimal.

Pertama Anda Lambdamempublikasikan pesan ke Anda SNS Topicdan yang kedua Lambdaberlangganan topik ini. Begitu pesan tiba di topik, keduaLambda dieksekusi dengan pesan sebagai parameter inputnya.

Lihat Meminta fungsi Lambda menggunakan notifikasi Amazon SNS .

Anda juga dapat menggunakan pendekatan ini untuk Menjalankan fungsi Lambda lintas-akun melalui SNS .

kixorz
sumber
2
Kinesis mungkin sedikit lebih rumit, tetapi jika Anda mencari solusi yang lebih kuat, maka itu mungkin pilihan yang baik untuk Anda. Juga, SNS tidak menyimpan acara yang masuk, Kinesis tidak.
kixorz
7
"Anda harus memadukan fungsi Lambda Anda melalui SNS" - dapatkah Anda mendukung ini dengan bukti / tautan ke dokumen? Saya melihat bagaimana kedua metode akan bekerja, saya akan tertarik melihat beberapa pendapat / pernyataan yang pasti di mana yang lebih disukai
Claude
30
Ini adalah ide yang bagus jika Anda membutuhkannya agar tidak sinkron. Tetapi jika fungsi lambda pertama Anda membutuhkan nilai yang dikembalikan dari lambda kedua, Anda harus rantai lambda dan memiliki fungsi lambda pertama memanggil fungsi lambda kedua secara langsung.
Noel Llevares
3
Saya tidak akan merekomendasikan menggunakan SNS. Anda bisa menggunakan API doa asinkron untuk fungsi lambda-tidak ada alasan untuk menggunakan SNS kecuali Anda ingin memberi tahu beberapa pelanggan dan tidak hanya memicu fungsi lambda lainnya.
6
Ingatlah bahwa SNS tidak memiliki jaminan pengiriman sehingga Anda dapat memecat pesan tetapi mungkin tidak sampai.
Bart Van Remortele
79

inilah kode contoh untuk 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, Anda perlu menambahkan kebijakan seperti ini ke peran lambda Anda juga

   {
        "Sid": "Stmt1234567890",
        "Effect": "Allow",
        "Action": [
            "lambda:InvokeFunction"
        ],
        "Resource": "*"
    }
kulit biru
sumber
Dokumentasi tampaknya menyarankan muatan harus JSON. Apakah mungkin mengirim data biner?
mbatchkarov
2
Saya lebih suka metode ini juga, tetapi ada satu kesalahan. Anda harus mengonversikannya datetime.now()menjadi string (atau menanganinya entah bagaimana). Jika tidak, Anda mendapatkan kesalahandatetime.datetime(2017, 9, 11, 14, 40, 53, 23834) is not JSON serializable
John C
Apakah mungkin untuk lebih membatasi dalam peran lambda pertama? Yaitu, untuk mengikatnya ke menjalankan fungsi tertentu , daripada apa pun?
Phil
@Phil mungkin bidang "Sumber Daya" dapat diatur untuk memungkinkan hanya satu set fungsi tertentu, saya tidak sepenuhnya yakin
blueskin
2
The InvocationTypeharus: RequestResponse. Untuk mendapatkan respons dari lambda yang Anda coba panggil.
ambigus9
31

Sejak pertanyaan ini diajukan, Amazon telah merilis Fungsi Langkah ( https://aws.amazon.com/step-functions/ ).

Salah satu prinsip inti di balik AWS Lambda adalah bahwa Anda dapat lebih fokus pada logika bisnis dan lebih sedikit pada logika aplikasi yang mengikat semuanya. Fungsi langkah memungkinkan Anda mengatur interaksi kompleks antar fungsi tanpa harus menulis kode untuk melakukannya.

dustinnoe
sumber
12

Solusi ini dilakukan dengan menggunakan boto3 dan 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
sumber
2
Jenis Invokasi Pilih dari opsi berikut. RequestResponse (default) - Aktifkan fungsi secara sinkron. Biarkan koneksi terbuka sampai fungsi mengembalikan respons atau waktu habis. Event - Aktifkan fungsi secara tidak sinkron. Kirim acara yang gagal beberapa kali ke antrian huruf mati fungsi (jika dikonfigurasi). DryRun - Validasi nilai parameter dan verifikasi bahwa pengguna atau peran memiliki izin untuk menjalankan fungsi.
Trilok Nagvenkar
11

Saya sedang melihat memotong SNS sampai saya melihat ini di dokumen klien Lambda (versi Java) :

Klien untuk mengakses AWS Lambda. Semua panggilan layanan yang dibuat menggunakan klien ini diblokir, dan tidak akan kembali sampai panggilan layanan selesai.

Jadi SNS memiliki keuntungan yang jelas: tidak sinkron. Lambda Anda tidak akan menunggu untuk lambda berikutnya selesai.

Ben Iggulden
sumber
17
InvocationType = 'Acara' menjadikannya async. docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/…
Ankit
3
@Ankit yang seharusnya menjadi jawaban yang dipilih, saya disesatkan untuk percaya menggunakan SNS adalah satu-satunya cara untuk melakukan doa asinkron karena tidak ada yang menjawab dengan informasi ini.
@Ankit apakah Anda tahu contoh menggunakan InvocationType = 'Acara' tetapi dari Jawa alih-alih JavaScript? Ada banyak dokumentasi Java, tetapi tidak sebanyak contoh JavaScript
Talador12
SNS masih menambahkan biaya untuk penggunaannya
Sebastien H.
1
@SebastienH. Tidak ada biaya untuk SNS memohon Lambda. aws.amazon.com/sns/pricing
fabdouglas
8

Amazon telah memperkenalkan fungsi langkah di AWS lambda pada 2016. Saya pikir, sekarang lebih nyaman menggunakan fungsi langkah karena sangat mudah untuk menggunakannya. Anda dapat membangun mesin negara dengan dua fungsi lambda sebagai:

  • untuk menghasilkan penawaran
  • mengubah kutipan menjadi pesanan

Anda dapat dengan mudah melakukannya seperti di bawah ini:

Di sini Anda dapat memiliki status pertama untuk menghasilkan kutipan dan yang lainnya berubah menjadi urutan

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

Fungsi langkah membuatnya sangat mudah untuk menulis beberapa fungsi lambda dan dijalankan secara berurutan atau paralel. Anda dapat memperoleh informasi lebih lanjut tentang fungsi langkah lambda di sini: Fungsi Langkah

Sunil Kapil
sumber
5

Saya bekerja dengan jawaban yang diberikan oleh blueskin tetapi saya tidak dapat membaca respons Payload karena InvocationType = 'Event' adalah async , jadi saya berubah sebagai InvocationType = 'RequestResponse' dan sekarang semua berfungsi dengan baik.

antonio
sumber
5

Di java, kita bisa melakukan hal berikut:

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

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

InvokeResult invokeResult = awsLambdaAsync.invoke(invokeRequest); 

Di sini, payload adalah objek java Anda yang di- string yang harus dilewatkan sebagai objek Json ke lambda lain jika Anda perlu meneruskan beberapa informasi dari memanggil lambda ke yang disebut lambda.

Suyash
sumber
2

Anda dapat menjalankan fungsi lambda secara langsung (setidaknya melalui Java) dengan menggunakan AWSLambdaClientseperti yang dijelaskan dalam posting blog AWS .

Neil
sumber
2

Saya mengalami masalah yang sama tetapi fungsi Lambda yang saya implementasikan akan memasukkan entri dalam DynamoDB, jadi solusi saya menggunakan DynamoDB Triggers.

Saya membuat DB memanggil fungsi Lambda untuk setiap sisipan / pembaruan dalam tabel, jadi ini memisahkan implementasi dua fungsi Lambda.

Dokumentasi ada di sini: http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Streams.Lambda.html

Berikut adalah panduan penelusuran: https://aws.amazon.com/blogs/aws/dynamodb-update-triggers-streams-lambda-cross-region-replication-app/

Lewen
sumber
1

Semacam solusi bundaran tetapi saya hanya memanggil titik akhir API untuk fungsi lambda saya ketika saya perlu rantai mereka. Ini memungkinkan Anda untuk memutuskan sambil mengkodekan apakah Anda ingin mereka tidak sinkron atau tidak.

Jika Anda tidak ingin mengatur permintaan POST, Anda hanya bisa mengatur permintaan GET sederhana dengan pasangan, atau tidak sama sekali, parameter string kueri untuk melewati peristiwa mudah.

- Edit -

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

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

Anselmus
sumber
1
ini sepertinya jauh lebih sedikit bundaran daripada SNS, tetapi kemudian saya tidak punya banyak pengalaman menggunakan SNS
Brandon
Bisakah Anda membagikan kode yang diperlukan untuk memanggil titik akhir API dari dalam lambda?
Glenn
@ Glenn itu hanya permintaan ajax. Beri tag pada parameter yang Anda perlukan sebagai parameter kueri. Lihat: docs.aws.amazon.com/apigateway/api-reference/… dan docs.aws.amazon.com/lambda/latest/dg/…
Anselm
4
Masalah lain adalah bahwa melalui API Gateway relatif mahal dibandingkan dengan memanggil fungsi Lambda lainnya. Fungsi 128MB berjalan untuk 100 ms (minimum) biaya $ 0,21 per 1 juta panggilan, sedangkan API Gateway biaya $ 3,50 per 1 juta. Jelas, jika Anda menjalankan lebih banyak waktu atau menggunakan lebih banyak ram, Anda harus melipatgandakan 21 sen, tetapi tetap saja, $ 3,50 per juta benar-benar mahal. (Harga ini berlaku mulai Agustus 2017)
Patrick Chu
1

Lainnya menunjukkan untuk menggunakan SQS dan Step Functions. Namun kedua solusi ini menambah biaya tambahan. Langkah Fungsi transisi keadaan konon sangat mahal.

AWS lambda menawarkan beberapa logika coba lagi. Di mana ia mencoba sesuatu selama 3 kali. Saya tidak yakin apakah itu masih berlaku ketika Anda memicu menggunakan API.

nnrales
sumber
0

Ini adalah contoh python untuk memanggil fungsi lambda lain dan mendapatkan responsnya. Ada dua jenis doa 'RequestResponse' dan 'Event' . Gunakan 'RequestResponse' jika Anda ingin mendapatkan respons fungsi lambda dan gunakan 'Event' untuk memanggil fungsi lambda secara tidak sinkron. Jadi kedua cara asinkron dan sinkron tersedia.

    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
sumber
-1

Anda dapat mengatur lingkungan 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
sumber