यह HTTP अनुरोध AWS लैम्ब्डा पर क्यों काम नहीं कर रहा है?


89

मैं AWS लाम्बा से शुरू कर रहा हूं और मैं अपने हैंडलर फ़ंक्शन से बाहरी सेवा का अनुरोध करने का प्रयास कर रहा हूं। इस उत्तर के अनुसार , HTTP अनुरोधों को ठीक काम करना चाहिए, और मुझे कोई भी दस्तावेज नहीं मिला है जो अन्यथा कहता है। (वास्तव में, लोगों ने कोड पोस्ट किए हैं जो एसएमएस भेजने के लिए टवीलियो एपीआई का उपयोग करते हैं ।)

मेरा हैंडलर कोड है:

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);
}

और मुझे अपने CloudWatch लॉग में निम्नलिखित 4 लाइनें दिखाई देती हैं:

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

मुझे वहाँ एक और लाइन की उम्मीद है:

2015-02-11 07:38:06 UTC eb19c89d-b1c0-11e4-bceb-d310b88d37e2 Got response: 302

लेकिन वह गायब है। यदि मैं अपने स्थानीय मशीन पर नोड में हैंडलर आवरण के बिना आवश्यक भाग का उपयोग कर रहा हूं, तो कोड अपेक्षित रूप से काम करता है।

inputfile.txtमैं उपयोग कर रहा हूँ के लिए है invoke-asyncकॉल यह है:

{
   "url":"http://www.google.com"
}

यह हैंडलर कोड के हिस्से की तरह लगता है जो अनुरोध को पूरी तरह से छोड़ देता है। मैंने अनुरोध परिवाद के साथ शुरू किया और httpएक न्यूनतम उदाहरण बनाने के लिए सादे का उपयोग करके वापस गिर गया । मैंने लॉग्स की जांच करने के लिए एक सेवा के URL का अनुरोध करने का भी प्रयास किया है और इसमें कोई अनुरोध नहीं है।

मैं पूरी तरह से स्टम्प्ड हूं। क्या कोई कारण है कि Node और / या AWS लैम्ब्डा HTTP अनुरोध को निष्पादित नहीं करेगा?


मुझे लगता है कि यह आपके HTTP अनुरोध में एक लापता उपयोगकर्ता-एजेंट के कारण हो सकता है।
मैमून अल-आकाश

4
लेखन के समय, यह वर्तमान में AWS मंचों के लैम्ब्डा फोरम में शीर्ष प्रश्न है। यह मुझे पागल कर रहा है और अन्य लोगों का एक समूह भी है।
नास्त्रेदमस

@ नोस्ट्राडमस मैं किसी भी अतिरिक्त प्रतिक्रिया, सुधार, और अपवोट्स की सराहना करता हूं। उन्हें यहां भेजें ;-)
awendt

1
मैंने ट्विलो उदाहरण से एलेक्सा नोड उदाहरण बंडल के साथ भेजे गए कुछ डिफ़ॉल्ट उदाहरणों और आपके संदर्भ.डोन () विधि के साथ सब कुछ करने की कोशिश की। http POST काम नहीं कर रहा है। क्या आपके POST अनुरोध कोड का पूरा नमूना पोस्ट करना संभव है?
छीलो

जवाबों:


79

बेशक, मैं समस्या को गलत समझ रहा था। जैसा कि AWS ने स्वयं इसे रखा था :

लैंबडा में पहली बार नोडज का सामना करने वालों के लिए, एक सामान्य त्रुटि यह भूल रही है कि कॉलबैक एसिंक्रोनस रूप से निष्पादित होता है और context.done()मूल हैंडलर में कॉल करता है जब आप वास्तव में एक और कॉलबैक (जैसे S3.PUT ऑपरेशन) के लिए इंतजार करना चाहते हैं, तो फ़ंक्शन को पूरा करने के लिए। अपने काम को अधूरा छोड़ने के लिए।

context.doneअनुरोध के लिए किसी भी कॉलबैक से पहले मैं फोन कर रहा था , जिससे समय से पहले मेरे कार्य की समाप्ति हो गई।

कार्य कोड यह है:

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);
    context.succeed();
  }).on('error', function(e) {
    console.log("Got error: " + e.message);
    context.done(null, 'FAILURE');
  });

  console.log('end request to ' + event.url);
}

अद्यतन: 2017 से AWS ने पुराने Nodejs 0.10 को हटा दिया है और केवल नया 4.3 रन-टाइम अब उपलब्ध है (पुराने कार्यों को अद्यतन किया जाना चाहिए)। इस रनटाइम ने हैंडलर फंक्शन में कुछ बदलाव किए। नए हैंडलर में अब 3 पैरामीटर हैं।

function(event, context, callback)

यद्यपि आप अभी भी पाएंगे succeed, doneऔर failसंदर्भ पैरामीटर पर, AWS callbackइसके बजाय फ़ंक्शन का उपयोग करने का सुझाव देता है या nullडिफ़ॉल्ट रूप से वापस आ जाता है।

callback(new Error('failure')) // to return error
callback(null, 'success msg') // to return ok

पूरा दस्तावेज http://docs.aws.amazon.com/lambda/latest/dg/nodejs-prog-model-handler.html पर पाया जा सकता है


4
तो, आप अपने हैंडलर कोड को कैसे काम करते हैं? मेरी समझ से आपको reference.done () को हटाने की आवश्यकता है ताकि कॉलबैक फ़ंक्शन को बुलाया जाएगा। लेकिन आपका कोड अभी भी मेरे लिए काम नहीं करता है। :(
म्बियै

3
context.done()कॉल कॉलबैक (सफलता और त्रुटि मामले के लिए) में चले गए की जरूरत है।
awendt

2
के रूप में मैं lambda के साथ आगे बढ़ने के लिए अपने मुद्दे को अभी तक नहीं है, लेकिन महान है।
डेविड

किसी भी विचार पर मैं अपने स्थानीय सिस्टम में लाम्बा से एपीआई कैसे कर सकता हूं?
अमित कुमार घोष

2
2017 अपडेट के साथ 2015 के प्रश्न को अपडेट करने के लिए सहारा!
ऐस

19

नोड का उपयोग करके एचटीपी अनुरोध का सरल कार्य उदाहरण।

const http = require('https')
exports.handler = async (event) => {
    return httprequest().then((data) => {
        const response = {
            statusCode: 200,
            body: JSON.stringify(data),
        };
    return response;
    });
};
function httprequest() {
     return new Promise((resolve, reject) => {
        const options = {
            host: 'jsonplaceholder.typicode.com',
            path: '/todos',
            port: 443,
            method: 'GET'
        };
        const req = http.request(options, (res) => {
          if (res.statusCode < 200 || res.statusCode >= 300) {
                return reject(new Error('statusCode=' + res.statusCode));
            }
            var body = [];
            res.on('data', function(chunk) {
                body.push(chunk);
            });
            res.on('end', function() {
                try {
                    body = JSON.parse(Buffer.concat(body).toString());
                } catch(e) {
                    reject(e);
                }
                resolve(body);
            });
        });
        req.on('error', (e) => {
          reject(e.message);
        });
        // send the request
       req.end();
    });
}

इसके लिए शुक्रिया। यह 2019 में इस पृष्ठ पर मेरे द्वारा देखा गया सबसे अच्छा जवाब है, अब यह कि लैम्ब्डा प्रतीक्षित वाक्यविन्यास का उपयोग कर रहा है।
तनीम टी

3
मुझे खोजने में एक घंटे से अधिक का समय लगा और सबसे अच्छे उत्तर के बाद node-fetch requestसे डिफ़ॉल्ट रूप से लंबोदर आदि उपलब्ध नहीं हैं।
एलेक्स सी।

बहुत से सैंपल कोड अब टूटे हुए लग रहे हैं। यह मार्च 2020 तक नमूना कोड काम कर रहा है, NWS.js 12.x के साथ AWS लैम्ब्डा का उपयोग करते हुए
मुहम्मद यूसुफ

क्या कोई समझा सकता है कि मेमने के कार्यों के अंदर डेटा के साथ POST अनुरोध कैसे करें?
पविन्दु

11

हाँ, अजीब जवाब एकदम सही है। मैं सिर्फ अपना कार्य कोड दिखाऊंगा ... मेरे पास संदर्भ था। आगे ('ब्ला'); reqPost.end () के बाद लाइन सही ; लाइन। इसे नीचे ले जाने से जहां मैं नीचे दिखाता हूं, सब कुछ हल हो गया है।

console.log('GW1');

var https = require('https');

exports.handler = function(event, context) {

    var body='';
    var jsonObject = JSON.stringify(event);

    // the post options
    var optionspost = {
        host: 'the_host',
        path: '/the_path',
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
        }
    };

    var reqPost = https.request(optionspost, function(res) {
        console.log("statusCode: ", res.statusCode);
        res.on('data', function (chunk) {
            body += chunk;
        });
        context.succeed('Blah');
    });

    reqPost.write(jsonObject);
    reqPost.end();
};

4

मुझे Node 10.X संस्करण पर इस मुद्दे का सामना करना पड़ा। नीचे मेरा काम कोड है।

const https = require('https');

exports.handler = (event,context,callback) => {
    let body='';
    let jsonObject = JSON.stringify(event);

    // the post options
    var optionspost = {
      host: 'example.com', 
      path: '/api/mypath',
      method: 'POST',
      headers: {
      'Content-Type': 'application/json',
      'Authorization': 'blah blah',
    }
    };

    let reqPost =  https.request(optionspost, function(res) {
        console.log("statusCode: ", res.statusCode);
        res.on('data', function (chunk) {
            body += chunk;
        });
        res.on('end', function () {
           console.log("Result", body.toString());
           context.succeed("Sucess")
        });
        res.on('error', function () {
          console.log("Result Error", body.toString());
          context.done(null, 'FAILURE');
        });
    });
    reqPost.write(jsonObject);
    reqPost.end();
};

3

मुझे बहुत ही समस्या थी और तब मुझे एहसास हुआ कि NodeJS में प्रोग्रामिंग वास्तव में पायथन या जावा से अलग है, क्योंकि यह जावास्क्रिप्ट पर आधारित है। मैं सरल अवधारणाओं का उपयोग करने की कोशिश करूंगा क्योंकि कुछ नए लोग हो सकते हैं जो रुचि रखते हैं या इस प्रश्न पर आ सकते हैं।

आइए निम्नलिखित कोड देखें:

var http = require('http'); // (1)
exports.handler = function(event, context) {
  console.log('start request to ' + event.url)
  http.get(event.url,  // (2)
  function(res) {  //(3)
    console.log("Got response: " + res.statusCode);
    context.succeed();
  }).on('error', function(e) {
    console.log("Got error: " + e.message);
    context.done(null, 'FAILURE');
  });

  console.log('end request to ' + event.url); //(4)
}

जब भी आप http पैकेज (1) में किसी विधि को कॉल करते हैं, तो इसे ईवेंट के रूप में बनाया जाता है और इस ईवेंट को अलग ईवेंट मिल जाता है। 'Get' फंक्शन (2) वास्तव में इस अलग ईवेंट का शुरुआती बिंदु है।

अब, (3) पर कार्य एक अलग घटना में निष्पादित किया जाएगा, और आपका कोड इसे निष्पादित पथ जारी रखेगा और सीधे (4) पर कूद जाएगा और इसे समाप्त कर देगा, क्योंकि ऐसा करने के लिए और कुछ नहीं है।

लेकिन (2) पर फायर की गई घटना अभी भी कहीं न कहीं अंजाम दे रही है और इसे खत्म होने में अपना मीठा समय लगेगा। बहुत विचित्र, सही? खैर, नहीं यह नहीं है। यह है कि NodeJS कैसे काम करता है और इसके बहुत महत्वपूर्ण आप इस अवधारणा के चारों ओर अपना सिर लपेटते हैं। यह वह जगह है जहाँ जावास्क्रिप्ट वादे मदद के लिए आते हैं।

आप जावास्क्रिप्ट वादों के बारे में और अधिक यहाँ पढ़ सकते हैं । संक्षेप में, आपको कोड इनलाइन के निष्पादन को बनाए रखने के लिए जावास्क्रिप्ट प्रॉमिस की आवश्यकता होगी और नए / अतिरिक्त थ्रेड्स को स्पॉन नहीं करेंगे।

अधिकांश आम NodeJS पैकेज में उनके API का एक प्रोमाइज़्ड संस्करण उपलब्ध होता है, लेकिन BlueBirdJS जैसे अन्य दृष्टिकोण हैं जो समान समस्या का समाधान करते हैं।

कोड जो आपने ऊपर लिखा था वह निम्न प्रकार से फिर से लिखा जा सकता है।

'use strict';
console.log('Loading function');
var rp = require('request-promise');
exports.handler = (event, context, callback) => {    

    var options = {
    uri: 'https://httpbin.org/ip',
    method: 'POST',
    body: {

    },
    json: true 
};


    rp(options).then(function (parsedBody) {
            console.log(parsedBody);
        })
        .catch(function (err) {
            // POST failed... 
            console.log(err);
        });

    context.done(null);
};

कृपया ध्यान दें कि उपरोक्त कोड सीधे काम नहीं करेगा यदि आप इसे एडब्ल्यूएस लैंबडा में आयात करेंगे। लैम्ब्डा के लिए, आपको कोड बेस के साथ मॉड्यूल को पैकेज करना होगा।


हाँ, वादे! हालांकि मैं context.done()कॉल को एक जंजीर finallyविधि में बदलने पर विचार करूंगा ।
20

3

मैंने अनुरोध करने के लिए विभिन्न तरीकों पर पूरे वेब पर बहुत सारे पोस्ट पाए हैं, लेकिन कोई भी ऐसा नहीं है जो वास्तव में दिखाता है कि प्रतिक्रिया को AWS लैम्ब्डा पर समान रूप से कैसे संसाधित किया जाए।

यहां एक नोड 6.10.3 लंबो फ़ंक्शन है जो एक https अनुरोध का उपयोग करता है, प्रतिक्रिया के पूरे शरीर को इकट्ठा करता है और लौटाता है, और processBodyपरिणामों के साथ एक असूचीबद्ध फ़ंक्शन को नियंत्रण देता है । मेरा मानना ​​है कि इस कोड में http और https विनिमेय हैं।

मैं async उपयोगिता मॉड्यूल का उपयोग कर रहा हूं , जो कि newbies के लिए समझना आसान है। आपको इसे उपयोग करने के लिए अपने AWS स्टैक पर धकेलने की आवश्यकता होगी (मैं सर्वर रहित रूपरेखा की सिफारिश करता हूं )।

ध्यान दें कि डेटा वापस विखंडन में आता है, जो एक वैश्विक चर में इकट्ठा होते हैं, और अंत में कॉलबैक को कहा जाता है जब डेटा endएड होता है।

'use strict';

const async = require('async');
const https = require('https');

module.exports.handler = function (event, context, callback) {

    let body = "";
    let countChunks = 0;

    async.waterfall([
        requestDataFromFeed,
        // processBody,
    ], (err, result) => {
        if (err) {
            console.log(err);
            callback(err);
        }
        else {
            const message = "Success";
            console.log(result.body);
            callback(null, message);
        }
    });

    function requestDataFromFeed(callback) {
        const url = 'https://put-your-feed-here.com';
        console.log(`Sending GET request to ${url}`);
        https.get(url, (response) => {
            console.log('statusCode:', response.statusCode);
            response.on('data', (chunk) => {
                countChunks++;
                body += chunk;
            });
            response.on('end', () => {
                const result = {
                    countChunks: countChunks,
                    body: body
                };
                callback(null, result);
            });
        }).on('error', (err) => {
            console.log(err);
            callback(err);
        });
    }
};

0

यहां छवि विवरण दर्ज करें

GET-Integration Request> मैपिंग सेक्शन के तहत एपीआई गेटवे में उपरोक्त कोड जोड़ें।


-14

हां, वास्तव में कई कारण हैं कि आप एडब्ल्यूएस लैंबडा जैसे और एचटीटीपी एंडपॉइंट का उपयोग क्यों कर सकते हैं।

AWS लाम्बा की वास्तुकला

यह एक microservice है। Amazon Linux AMI (संस्करण 3.14.26–24.46.amzn1.x86_64) के साथ EC2 के अंदर चल रहा है और Node.js. के साथ चलता है। मेमोरी को बीटवैन 128mb और 1gb किया जा सकता है। जब डेटा स्रोत घटना को चालू करता है, तो विवरण लंबर फ़ंक्शन के लिए पैरामीटर के रूप में पारित किया जाता है।

क्या हुआ?

AWS लैंबडा एक कंटेनर के अंदर चलता है, और कोड सीधे पैकेज या मॉड्यूल के साथ इस कंटेनर में अपलोड किया जाता है। उदाहरण के लिए, हम आपके lambda फ़ंक्शन को चलाने वाली linux मशीन के लिए SSH कर सकते हैं। केवल वही चीजें जिन्हें हम मॉनिटर कर सकते हैं वे हैं, CloudWatchLogs और रनटाइम से आए अपवाद।

AWS लॉन्च का ख्याल रखती है और हमारे लिए कंटेनरों को समाप्त करती है, और बस कोड को चलाती है। इसलिए, यहां तक ​​कि आपको आवश्यकता होती है ('http'), यह काम करने वाला नहीं है, क्योंकि यह कोड जिस स्थान पर चलता है, वह इसके लिए नहीं बनाया गया था।


5
आपको मेरी समस्या गलत लगी। मुझे पता है कि लैंबडा कोड एक कंटेनर में चलाया जा रहा है, और मुझे पता है कि मैं अंतर्निहित मशीन का उपयोग नहीं कर सकता। न ही मैं अंदर जाने की कोशिश कर रहा हूं, मेरा कोड बाहर निकलने की कोशिश कर रहा है, अर्थात बाहरी समापन बिंदुओं तक पहुंच है, और लैम्ब्डा ऐसा कर सकता है। समस्या पूरी तरह से कुछ और थी, जैसा कि मैंने अपने जवाब में बताया है।
awendt
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.