本文介绍了为什么此 HTTP 请求在 AWS Lambda 上不起作用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开始使用 AWS Lambda,我正在尝试从我的处理程序函数请求外部服务.根据这个答案,HTTP 请求应该可以正常工作,而且我还没有找到任何其他说明的文档.(实际上,人们已经发布了使用 Twilio API 发送短信的代码.)

I'm getting started with AWS Lambda and I'm trying to request an external service from my handler function. According to this answer, HTTP requests should work just fine, and I haven't found any documentation that says otherwise. (In fact, people have posted code that use the Twilio API to send SMS.)

我的处理程序代码是:

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 行:

and I see the following 4 lines in my CloudWatch logs:

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

但那是缺失的.如果我在本地机器上的 node 中使用没有处理程序包装器的基本部分,代码会按预期工作.

but that's missing. If I'm using the essential part without the handler wrapper in node on my local machine, the code works as expected.

我使用的 inputfile.txt 用于 invoke-async 调用是这样的:

The inputfile.txt I'm using is for the invoke-async call is this:

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

似乎完全跳过了执行请求的处理程序代码部分.我从 request lib 开始,然后回到使用普通的 http 来创建一个最小的例子.我还尝试请求我控制的服务的 URL 以检查日志,但没有请求进来.

It seems like the part of the handler code that does the request is skipped entirely. I started out with the request lib and fell back to using plain http to create a minimal example. I've also tried to request a URL of a service I control to check the logs and there's no requests coming in.

我完全被难住了.Node 和/或 AWS Lambda 是否有任何原因不执行 HTTP 请求?

推荐答案

当然,我误解了这个问题.正如 AWS 自己所说:

Of course, I was misunderstanding the problem. As AWS themselves put it:

对于那些在 Lambda 中第一次遇到 nodejs 的人来说,一个常见的错误是忘记回调异步执行并调用context.done() 在您真正打算等待时的原始处理程序中另一个回调(例如 S3.PUT 操作)完成,强制因工作未完成而终止的函数.

我在触发请求的任何回调之前调用了 context.done,导致我的函数提前终止.

I was calling context.done way before any callbacks for the request fired, causing the termination of my function ahead of time.

工作代码是这样的:

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 个参数.

Update: starting 2017 AWS has deprecated the old Nodejs 0.10 and only the newer 4.3 run-time is now available (old functions should be updated). This runtime introduced some changes to the handler function. The new handler has now 3 parameters.

function(event, context, callback)

尽管您仍会在上下文参数上找到succeeddonefail,但AWS 建议使用callback 函数,否则默认返回 null.

Although you will still find the succeed, done and fail on the context parameter, AWS suggest to use the callback function instead or null is returned by default.

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

这篇关于为什么此 HTTP 请求在 AWS Lambda 上不起作用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-04 05:43