Ich beginne mit AWS Lambda und versuche, einen externen Service von meiner Handlerfunktion anzufordern. Nach dieser Antwort sollten HTTP-Anforderungen einwandfrei funktionieren, und ich habe keine Dokumentation gefunden, die etwas anderes besagt. (Tatsächlich haben Benutzer Code veröffentlicht, der die Twilio-API zum Senden von SMS verwendet .)
Mein Handler-Code lautet:
var http = require('http');
exports.handler = function(event, context) {
console.log('start request to ' + event.url)
http.get(event.url, function(res) {
console.log("Got response: " + res.statusCode);
}).on('error', function(e) {
console.log("Got error: " + e.message);
});
console.log('end request to ' + event.url)
context.done(null);
}
und ich sehe die folgenden 4 Zeilen in meinen CloudWatch-Protokollen:
2015-02-11 07:38:06 UTC START RequestId: eb19c89d-b1c0-11e4-bceb-d310b88d37e2
2015-02-11 07:38:06 UTC eb19c89d-b1c0-11e4-bceb-d310b88d37e2 start request to http://www.google.com
2015-02-11 07:38:06 UTC eb19c89d-b1c0-11e4-bceb-d310b88d37e2 end request to http://www.google.com
2015-02-11 07:38:06 UTC END RequestId: eb19c89d-b1c0-11e4-bceb-d310b88d37e2
Ich würde dort eine weitere Zeile erwarten:
2015-02-11 07:38:06 UTC eb19c89d-b1c0-11e4-bceb-d310b88d37e2 Got response: 302
aber das fehlt. Wenn ich den wesentlichen Teil ohne den Handler-Wrapper im Knoten auf meinem lokalen Computer verwende, funktioniert der Code wie erwartet.
Das, was inputfile.txt
ich benutze, ist für den invoke-async
Anruf:
{
"url":"http://www.google.com"
}
Es scheint, dass der Teil des Handler-Codes, der die Anforderung ausführt, vollständig übersprungen wird. Ich begann mit der Anfrage lib und benutzte einfach http
, um ein minimales Beispiel zu erstellen. Ich habe auch versucht, eine URL eines von mir kontrollierten Dienstes anzufordern, um die Protokolle zu überprüfen, und es gehen keine Anfragen ein.
Ich bin total ratlos. Gibt es einen Grund, warum Node und / oder AWS Lambda die HTTP-Anforderung nicht ausführen würden?
Antworten:
Natürlich habe ich das Problem falsch verstanden. Wie AWS selbst sagte :
Ich habe lange
context.done
vor einem Rückruf für die angeforderte Anfrage angerufen und meine Funktion vorzeitig beendet.Der Arbeitscode lautet:
Update: Ab 2017 hat AWS die alten Nodejs 0.10 veraltet und nur die neuere 4.3-Laufzeit ist jetzt verfügbar (alte Funktionen sollten aktualisiert werden). Diese Laufzeit führte einige Änderungen an der Handlerfunktion ein. Der neue Handler hat jetzt 3 Parameter.
Obwohl Sie immer noch das finden wird
succeed
,done
undfail
auf dem Kontextparameter, schlagen AWS die verwendet werdencallback
Funktion statt odernull
wird standardmäßig zurückgegeben.Die vollständige Dokumentation finden Sie unter http://docs.aws.amazon.com/lambda/latest/dg/nodejs-prog-model-handler.html
quelle
context.done()
Anruf muss in die Rückrufe verschoben werden (für Erfolg und Fehler).Einfaches Arbeitsbeispiel für eine HTTP-Anforderung unter Verwendung eines Knotens.
quelle
node-fetch
request
usw. auf Lambda standardmäßig nicht verfügbar sind.Ja, eine Antwort ist perfekt. Ich zeige nur meinen Arbeitscode ... Ich hatte den Kontext. Erfolgreich ('Blah'); Zeile direkt nach dem reqPost.end (); Linie. Das Verschieben an die Stelle, an der ich unten zeige, hat alles gelöst.
quelle
Ich habe dieses Problem in der Node 10.X-Version festgestellt. Unten ist mein Arbeitscode.
quelle
Ich hatte das gleiche Problem und dann wurde mir klar, dass sich die Programmierung in NodeJS tatsächlich von Python oder Java unterscheidet, da sie auf JavaScript basiert. Ich werde versuchen, einfache Konzepte zu verwenden, da es möglicherweise einige neue Leute gibt, die interessiert wären oder zu dieser Frage kommen könnten.
Schauen wir uns den folgenden Code an:
Wenn Sie eine Methode in http package (1) aufrufen, wird sie als Ereignis erstellt und dieses Ereignis erhält ein separates Ereignis. Die 'get'-Funktion (2) ist eigentlich der Ausgangspunkt dieses separaten Ereignisses.
Jetzt wird die Funktion bei (3) in einem separaten Ereignis ausgeführt, und Ihr Code setzt den Ausführungspfad fort und springt direkt zu (4) und beendet ihn, da nichts mehr zu tun ist.
Aber das bei (2) abgefeuerte Ereignis wird immer noch irgendwo ausgeführt und es wird seine eigene süße Zeit brauchen, um zu beenden. Ziemlich bizarr, oder? Nein, ist es nicht. So funktioniert NodeJS und es ist ziemlich wichtig, dass Sie sich mit diesem Konzept beschäftigen. Dies ist der Ort, an dem JavaScript-Versprechen helfen.
Weitere Informationen zu JavaScript-Versprechen finden Sie hier . Kurz gesagt, Sie benötigen ein JavaScript-Versprechen, um die Ausführung von Code inline zu halten, und es werden keine neuen / zusätzlichen Threads erzeugt.
Die meisten gängigen NodeJS-Pakete verfügen über eine versprochene Version ihrer API, es gibt jedoch auch andere Ansätze wie BlueBirdJS, mit denen das ähnliche Problem behoben werden kann.
Der Code, den Sie oben geschrieben haben, kann wie folgt lose neu geschrieben werden.
Bitte beachten Sie, dass der obige Code nicht direkt funktioniert, wenn Sie ihn in AWS Lambda importieren. Für Lambda müssen Sie die Module auch mit der Codebasis verpacken.
quelle
context.done()
Aufruf in eine verkettetefinally
Methode zu verschieben.Ich habe im Internet viele Beiträge zu den verschiedenen Möglichkeiten gefunden, die Anfrage zu bearbeiten, aber keine, die tatsächlich zeigen, wie die Antwort auf AWS Lambda synchron verarbeitet wird.
Hier ist eine Lambda-Funktion des Knotens 6.10.3, die eine https-Anforderung verwendet, den gesamten Text der Antwort sammelt und zurückgibt und die Steuerung
processBody
mit den Ergebnissen an eine nicht aufgeführte Funktion übergibt . Ich glaube, dass http und https in diesem Code austauschbar sind.Ich verwende das asynchrone Dienstprogrammmodul , das für Neulinge leichter zu verstehen ist. Sie müssen dies auf Ihren AWS Stack übertragen, um es verwenden zu können (ich empfehle das serverlose Framework ).
Beachten Sie, dass die Daten in Blöcken zurückkommen, die in einer globalen Variablen gesammelt sind, und schließlich der Rückruf aufgerufen wird, wenn die Daten
end
bearbeitet wurden.quelle
Ja, es gibt tatsächlich viele Gründe, warum Sie auf AWS Lambda like und HTTP Endpoint zugreifen können.
Die Architektur von AWS Lambda
Es ist ein Microservice. Läuft in EC2 mit Amazon Linux AMI (Version 3.14.26–24.46.amzn1.x86_64) und läuft mit Node.js. Der Speicher kann zwischen 128 MB und 1 GB liegen. Wenn die Datenquelle das Ereignis auslöst, werden die Details als Parameter an eine Lambda-Funktion übergeben.
Was ist los?
AWS Lambda wird in einem Container ausgeführt, und der Code wird mit Paketen oder Modulen direkt in diesen Container hochgeladen. Zum Beispiel können wir NIEMALS SSH für den Linux-Rechner ausführen, auf dem Ihre Lambda-Funktion ausgeführt wird. Die einzigen Dinge, die wir überwachen können, sind die Protokolle mit CloudWatchLogs und der Ausnahme, die von der Laufzeit kam.
AWS kümmert sich für uns um das Starten und Beenden der Container und führt einfach den Code aus. Selbst wenn Sie require ('http') verwenden, wird es nicht funktionieren, da der Ort, an dem dieser Code ausgeführt wird, nicht dafür gemacht wurde.
quelle