7

我编写了 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”,“代码”:“ETIMEDOUT”,“errno”:“ETIMEDOUT”,“系统调用”:“连接”,“地址” :“34.255.225.41”,“端口”:443,“堆栈”:[“错误:连接 ETIMEDOUT 34.255.225.41:443”,“在 TCPConnectWrap.afterConnect [as oncomplete] (net.js:1107:14)”] }

4

1 回答 1

8

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

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

在 AWS 中,VPC 提供了一个“公共”网络和一个“私有”网络,其中 VPC 中的所有资源都可以与 VPC 中的其他资源进行通信,无论它们位于哪个网段。VPC公共段上的任何资源都将通过 Internet 网关路由公共 Internet 绑定流量,该网关在大多数 VPC 上提供,开箱即用。但是,在 VPC 的私有网段上设置的任何容器/资源都受到防火墙保护,并且在没有安装 NAT 的情况下没有公共互联网地址的路由。

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

由于所有 AWS 服务资源通常都通过其面向公众的服务域名(例如从 AWS S3)访问,因此尝试在没有 NAT 网关的 VPC 后面的 Lambda 中访问它们将导致您的函数接收ETIMEDOUT错误。

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

如果您的函数需要在 VPC 之后才能访问其他资源,那么您应该在您的 VPC 上设置一个 NAT 网关。有关如何执行此操作的更多信息,请参阅AWS 文档。否则,您应确保您的 Lambda设置为使用 VPC,因为在 VPC 内运行它会导致额外的冷启动时间延迟以及网络连接挑战。

于 2019-11-21T01:39:37.693 回答