AWS Lambda işlevi başka bir tane çağırabilir mi


320

2 Lambda fonksiyonları var - biri bir teklif üreten ve bir teklif bir sipariş dönüştürür. Sipariş lambda işlevinin sadece güvenilir olmayan bir istemciden almak yerine, teklifi yeniden oluşturmak için Alıntı işlevini çağırmasını istiyorum.

Aklıma gelen her yere baktım - fakat zincirleme ya da fonksiyonları çağırmaya nasıl devam ettiğimi göremiyorum ... elbette bu var!


1
Burada ulaşan, ancak öncelikle Lambda işlevinde AWS JavaScript SDK bağlı yüzden gelemedi, bir oluşturmak ediyorum AWS.Lambda istemcisi ve çağırmak ikinci işlevi?
devonlazarus

Bunu deneyeceğim - ama bunun nasıl yapılacağından tam olarak emin değildim, çünkü başka bir Lambda işlevinden yapmanın herhangi bir örneği yoktu.
Gümüş

1
görünüşe göre HTTP aracılığıyla Lambda fonksiyonunu da çağırabilirsiniz .
devonlazarus

4
ve bir fikir daha, onları SNS aracılığıyla zincirleyebilirsiniz , bu muhtemelen daha ölçeklenebilir bir strateji olarak gitmem yoludur
devonlazarus

6
Burada bahsedilmeyen diğer bir yaygın alternatif Adım Fonksiyonları veya SWF'dir.
lebryant

Yanıtlar:


365

Kullanarak bir yol buldum 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)
  }
});

Dokümanı burada bulabilirsiniz: http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/Lambda.html


28
SNS kullanmak muhtemelen daha iyi bir yaklaşımdır, ancak bu doğru cevaptır.
Silver

29
yanlış olabilir, ama sanırım çağrışım ilk lambda ikinci lambda sona ermesini bekler, böylece her iki lambda çalışırken ücretleri tahakkuk olacak. SNS kullanarak, ilk lambda sonlanmalı ve ikinci lambda'nın bağımsız olarak çalışmasına izin vermelidir.
dev

81
Bu InvocationType: 'Event'parametre sayesinde çalışmak için başardı ( FunctionNameve sonra ekleyin Payload). Dokümanlar'dan: "Olayı InvocationType olarak belirterek isteğe bağlı olarak eşzamansız yürütme isteyebilirsiniz." Zaman uyumsuz yürütme ile, geri çağrı işlevi güvenilir bir şekilde çağrılır, ancak çağrılan lambda'nın yürütmeyi bitirmesini beklemek zorunda kalmadan.
Alessandro

25
Çağıran lambda işlevinin rolünün IAM ilkesini içermesi gerektiğini unutmayın AWSLambdaRole. Veya rolünüzün mevcut politikasına aşağıdaki ifade nesnesini ekleyebilirsiniz: '{"Efekt": "İzin Ver", "Eylem": ["lambda: InvokeFunction"], "Kaynak": ["*"]} `
Bob Arlof

4
Aslında AWS, başka bir lambdadan bir lambda çağırmak zorunda kalmadan birden fazla lambda çağırmanıza izin veren StepFunctions'ı serbest bıraktı, yani. birincisi, ikincisinin bitmesini "beklemez"
Sebastien H.

116

Lambda functionsYoluyla zincirleme gerekir SNS. Bu yaklaşım, minimum çaba için iyi performans, gecikme ve ölçeklenebilirlik sağlar.

İlk Lambdamesajınız size mesaj yayınlar SNS Topicve ikincisi Lambdabu konuya abone olur. Mesajlar konuya ulaşır ulaşmaz, ikinci Lambdamesaj girdi parametresi olarak mesajla yürütülür.

Bkz . Amazon SNS bildirimlerini kullanarak Lambda işlevlerini başlatma .

Bu yaklaşımı, SNS yoluyla hesaplar arası Lambda işlevlerini çağırmak için de kullanabilirsiniz .


2
Kinesis biraz daha karmaşık olabilir, ancak daha sağlam bir çözüm arıyorsanız, sizin için iyi bir seçenek olabilir. Ayrıca, SNS gelen olayları saklamaz, Kinesis yapar.
kixorz

7
"Lambda fonksiyonlarınızı SNS ile zincirlemelisiniz" - bunu kanıtlarla / dokümanlarla bağlantılarla destekleyebilir misiniz? Her iki yöntemin nasıl çalışacağını görüyorum, hangisinin tercih edileceği konusunda bazı görüşler / kesin ifadeler görmek isterim
Claude

30
Eşzamansız olması gerekiyorsa, bu iyi bir fikirdir. Ancak, ilk lambda işlevinizin ikinci lambda'dan döndürülen değere ihtiyacı varsa, lambdaları zincirlemeniz ve ilk lambda işlevinin doğrudan ikinci lambda işlevini çağırmasını sağlamanız gerekir.
Noel Llevares

3
SNS kullanmanızı tavsiye etmem. Lambda işlevi için eşzamansız çağırma API'sini kullanabilirsiniz - birden fazla aboneyi bilgilendirmek ve sadece başka bir lambda işlevini tetiklemek istemiyorsanız SNS kullanmak için hiçbir neden yoktur.

6
SNS'nin teslimat garantisi olmadığını, bu nedenle iletiyi tetikleyebileceğinizi, ancak gelmeyebileceğini unutmayın.
Bart Van Remortele

79

İşte python için örnek bir kod,

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, lambda rolünüze de böyle bir politika eklemeniz gerekir

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

Belgeler, yükün JSON olması gerektiğini gösteriyor. İkili veri göndermek mümkün müdür?
mbatchkarov

2
Bu yöntemi de tercih ediyorum, ama bir aksaklığı var. datetime.now()Bir dizeye dönüştürmeniz (veya bir şekilde işlemeniz) gerekir. Aksi takdirde, hatayı alırsınızdatetime.datetime(2017, 9, 11, 14, 40, 53, 23834) is not JSON serializable
John C

İlk lambda rolünde daha kısıtlayıcı olmak mümkün mü? Yani, herhangi birinden ziyade belirli işlevleri çağırmak için onu bağlamak için ?
Phil

@Phil belki "Kaynak" alanı sadece belirli bir dizi fonksiyona izin verecek şekilde ayarlanabilir, yine de tam olarak emin değilim
blueskin

2
InvocationTypeOlmalıdır: RequestResponse. Çağırmaya çalıştığınız lambda'dan yanıt almak için.
ambigus9

31

Bu soru sorulduğundan, Amazon Adım İşlevleri'ni ( https://aws.amazon.com/step-functions/ ) yayınladı .

AWS Lambda'nın arkasındaki temel ilkelerden biri, daha çok iş mantığına ve daha azını birbirine bağlayan uygulama mantığına daha az odaklanabilmenizdir. Adım işlevleri, kodu yazmak zorunda kalmadan işlevler arasındaki karmaşık etkileşimleri düzenlemenize olanak tanır.


12

Bu çözüm boto3 ve Python kullanılarak yapılır:

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 Aşağıdaki seçeneklerden birini seçin. RequestResponse (varsayılan) - İşlevi senkronize olarak çağırır. İşlev bir yanıt döndürene veya zaman aşımına uğrayana kadar bağlantıyı açık tutun. Event - İşlevi zaman uyumsuz olarak çağırır. Birden çok başarısız olan olayları işlevin ölü harf kuyruğuna (yapılandırılmışsa) gönderin. DryRun - Parametre değerlerini doğrulayın ve kullanıcının veya rolün işlevi başlatma iznine sahip olduğunu doğrulayın.
Trilok Nagvenkar

11

Lambda istemci belgelerinde (Java sürümü) görene kadar SNS kesmeye bakıyordum :

AWS Lambda'ya erişim istemcisi. Bu istemci kullanılarak yapılan tüm servis çağrıları engelleniyor ve servis çağrısı tamamlanana kadar geri dönmeyecek.

Yani SNS'in bariz bir avantajı var: asenkron. Lambda'nız sonraki lambda'nın tamamlanmasını beklemez.


17
InvocationType = 'Olay', zaman uyumsuz hale getirir. docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/…
Ankit

3
@ Seçilen cevap olması gereken bir takım olarak, SNS kullanmanın eşzamansız bir çağrının tek yolu olduğuna inanmak için yanıldım çünkü kimse bu bilgilerle cevap vermedi.

@Ankit InvocationType = 'Event' kullanan ancak JavaScript yerine Java'dan bir örnek biliyor musunuz? Bir ton Java belgesi var, ancak JavaScript kadar fazla örnek yok
Talador12

SNS hala kullanımı için maliyetler ekliyor
Sebastien H.

1
@SebastienH. Lambda'yı çağıran SNS için herhangi bir ücret yoktur. aws.amazon.com/sns/pricing
fabdouglas

8

Amazon, 2016 yılında AWS lambda'da adım fonksiyonları tanıttı. İki lambda işlevine sahip bir durum makinesi oluşturabilirsiniz:

  • alıntı yapmak
  • teklifi siparişe dönüştürür

Bunu aşağıdaki gibi kolayca yapabilirsiniz:

Burada bir fiyat teklifi için ilk duruma sahip olabilir ve diğeri sıraya dönüşebilir

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

Adım fonksiyonları, çoklu lambda fonksiyonlarının yazılmasını ve sırayla veya paralel olarak çalıştırılmasını gerçekten kolaylaştırır. Lambda adımları işlevleri hakkında daha fazla bilgiyi burada bulabilirsiniz: Adımlar İşlevleri


5

Blueskin tarafından verilen cevapla çalışıyordum ama InvocationType = 'Event' zaman uyumsuz olduğu için Payload yanıtını okuyamadım , bu yüzden InvocationType = 'RequestResponse' olarak değiştim ve şimdi hepsi iyi çalışıyor.


5

Java'da şunları yapabiliriz:

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

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

InvokeResult invokeResult = awsLambdaAsync.invoke(invokeRequest); 

Burada, yük, lambda'yı çağırmak için lambda olarak adlandırılan bazı bilgileri aktarmanız gerektiğinde, Json nesnesi olarak başka bir lambda'ya geçirilmesi gereken dizilmiş java nesnenizdir.



2

Lambda işlevini AWSLambdaClientAWS'nin blog gönderisinde açıklandığı gibi kullanarak doğrudan (en azından Java aracılığıyla) başlatabilirsiniz .


2

Aynı sorunu yaşıyorum ama benim uygulama DynamoDB Tetikleyicileri kullanır, ben uyguladığım Lambda işlevi DynamoDB bir girdi ekler.

DB tablodaki her ekleme / güncelleştirme için bir Lambda işlevi çağırmak, bu nedenle bu iki Lambda işlevlerinin uygulanmasını ayırır.

Belgeler burada: http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Streams.Lambda.html

İşte rehberli bir kılavuz: https://aws.amazon.com/blogs/aws/dynamodb-update-triggers-streams-lambda-cross-region-replication-app/


1

Bir dolambaçlı çözüm tür ama sadece onları zinciri gerektiğinde lambda fonksiyonları için API uç noktasını çağırmak . Bu, kodlama yaparken eşzamansız olmalarını isteyip istemediğinize karar vermenizi sağlar.

Bir POST isteği ayarlamak istemiyorsanız, kolay olay iletimi için bir çift veya hiç sorgu sorgusu ile basit bir GET isteği ayarlayabilirsiniz.

-- Düzenle --

Bkz. Https://docs.aws.amazon.com/apigateway/api-reference/making-http-requests/

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


1
Bu SNS daha çok dolambaçlı gibi görünüyor, ama sonra SNS kullanarak çok deneyimim yok
Brandon

Bir API uç noktasını çağırmak için gereken kodu lambda içinden paylaşabilir misiniz?
Glenn

@Glenn bu sadece bir ajax isteği. Sorgu parametreleri olarak ihtiyacınız olan parametrelerinizi etiketleyin. Bkz. Docs.aws.amazon.com/apigateway/api-reference/… ve docs.aws.amazon.com/lambda/latest/dg/…
Anselm

4
Başka bir sorun, API Ağ Geçidi'nden geçmenin başka bir Lambda işlevi çağırmaya kıyasla nispeten pahalı olmasıdır. 100ms (minimum) için çalışan 128MB'lık bir işlev 1 milyon arama için 0,21 ABD doları, API Ağ Geçidi 1 milyon için 3,50 ABD dolarıdır. Açıkçası, daha fazla zaman için koşuyorsanız veya daha fazla koç kullanıyorsanız, 21 sent'i çarpmanız gerekir, ancak yine de milyonda 3,50 dolar gerçekten pahalıdır. (Bu fiyatlar Ağustos 2017 itibarıyla geçerlidir)
Patrick Chu

1

Diğerleri SQS ve Step Fonksiyonlarını kullandıklarına dikkat çekti. Ancak bu çözümlerin her ikisi de ek maliyet sağlar. Adım İşlev durum geçişlerinin çok pahalı olduğu tahmin edilmektedir.

AWS lambda bazı yeniden deneme mantığı sunar. Burada 3 kez bir şey dener. API'yı kullandığınızda bunun hala geçerli olup olmadığından emin değilim.


0

İşte başka bir lambda işlevini çağırmanın python örneği ve yanıtını alır. 'RequestResponse' ve 'Event' olmak üzere iki çağrı türü vardır . Lambda işlevinin yanıtını almak istiyorsanız 'RequestResponse' seçeneğini kullanın ve lambda işlevini eşzamansız olarak çağırmak için 'Event'i kullanın. Böylece eşzamansız ve eşzamanlı olarak kullanılabilir.

    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 ortamını ayarlayabilirsiniz.

assert(process.env.AWS_REGION, 'Missing AWS_REGION env (eg. ap-northeast-1)');
const aws = require('aws-sdk');
const lambda = new aws.Lambda();
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.