使用Node Js的AWS Lambda在http.request()上提供“ connect ETIMEDOUT”

时间:2019-11-13 09:50:52

标签: node.js amazon-web-services ecmascript-6 aws-lambda nodejs-server

我编写了lambda函数,每当在s3存储桶上创建任何新对象时,该函数都会检索s3 Url。 检索s3Url后,该lambda发出请求通过REST调用发送到我的服务器。

我观察了云观察者。 无法将请求发送到我的服务器 我不想在我的lambda中使用外部软件包,我想使其轻巧,这就是为什么我使用nodeJ的原因 https。

这是我的Lambda代码

 exports.handler =  (event,context,callback) => {
  // Extract S3 Url and id From S3 object present in event
  const https = require('https');
  let {s3 , awsRegion} = event["Records"][0];
  let {object : {key}, bucket : {name}} = s3;
  let s3URL = `https://${name}.s3.${awsRegion}.amazonaws.com/${key}`;
  console.log("sURL",s3URL);
  let _id = key.split('/')[0];
  console.log("id",_id);
//Making http request to my server
  let body='';
  // the post options
  let optionsPost = {
     host: 'xyz.abc.com', 
    path: '/api/v1/apipath',
    method: 'POST',
    headers: {
    'Content-Type': 'application/json',
    'Authorization': 'XYZ',
    'id' : _id
  }
  };
  const keepAliveAgent = new https.Agent({ keepAlive: true });
  optionsPost.agent = keepAliveAgent;
  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');
        callback(new Error('failure')) // to return error
      });
  });
  reqPost.write(JSON.stringify({ s3Url: s3URL,userName: 'SYSTEM' }));
  reqPost.end();
};

这是我的云监控器错误

  

{“ errorType”:“错误”,“ errorMessage”:“连接ETIMEDOUT 34.255.225.41:443”,“ code”:“ ETIMEDOUT”,“ errno”:“ ETIMEDOUT”,“ syscall”:“连接”, “ address”:“ 34.255.225.41”,“ port”:443,“ stack”:[“错误:在TCPConnectWrap.afterConnect上连接ETIMEDOUT 34.255.225.41:443”,“ [oncomplete](net.js:1107:14 )“]}

1 个答案:

答案 0 :(得分:2)

如果您尝试通过AWS开发工具包或直接通过Lambda进行任何HTTP调用来访问S3(或其他AWS资源),则以下两种情况之一必须为真:

  • 您的Lambda未设置为在VPC中运行
  • 您的Lambda设置为在VPC中运行,并且VPC设置为NAT gateway

在AWS中,VPC提供了一个“ 公共”网络和一个“ 私有”网络,其中VPC中的所有资源都可以与VPC中的其他资源进行通信,而无论哪个分段他们在。 VPC的 public 段上的任何资源都将通过大多数VPC上提供的Internet网关直接路由与公共Internet绑定的流量。但是,在VPC的私有网段上设置的所有容器/资源都经过防火墙保护,并且在未安装NAT的情况下无法路由公用Internet地址。

当调用配置为在VPC内运行的Lambda函数时,将在VPC的 private 段中创建运行代码的容器。没有NAT,Lambda只能通过其内部IP地址/ DNS名称访问VPC中的任何资源。

由于通常从面向公共服务的域名(例如,从AWS S3)访问所有AWS服务资源,因此尝试在不具有NAT网关的VPC后面的Lambda中访问它们将导致您的函数收到{{1 }}错误。

出于相同原因在Lambda中使用AWS开发工具包时也会发生这种情况。

如果您的功能需要位于VPC后面才能访问其他资源,则应在VPC上设置NAT网关。 AWS Documentation中提供了有关如何执行此操作的更多信息。否则,您应确保设置您的Lambda以使用VPC,因为在VPC中运行Lambda会导致额外的冷启动时间延迟以及网络连接挑战。