简体   繁体   English

为什么我的 AWS lambda function 在使用私有 elasticache.network 调用以及外部 API 调用时随机失败?

[英]Why Does my AWS lambda function randomly fail when using private elasticache network calls as well as external API calls?

I am trying to write a caching function that returns cached elasticcache data or makes an api call to retrieve that data.我正在尝试编写一个缓存 function 来返回缓存的 elasticcache 数据或进行 api 调用以检索该数据。 However, the lambda function seems to be very unrealiable and timing out often.但是,lambda function 好像很不靠谱,经常超时。

It seems that the issue is having redis calls as well as public api calls causes the issue.问题似乎是有 redis 电话以及公共 api 电话导致了这个问题。 I can confirm that I have setup aws correctly with a su.net with an inte.net gateway and a private su.net with a nat gateway.我可以确认我已经使用带有 inte.net 网关的 su.net 和带有 nat 网关的私有 su.net 正确设置了 aws。 The function works, but lonly 10 % of the time.The remaining times exceution is stopped right before making the API call. function 有效,但只有 10% 的时间。剩余时间的执行在拨打 API 之前停止。 I have also noticed that the api calls fail after creating the redis client.我还注意到在创建 redis 客户端后 api 调用失败。 If I make the external api call prior to making the redis check it seems the function is a lot more reliable and doesn't time out.如果我在进行 redis 检查之前进行外部 api 调用,那么 function 似乎更可靠并且不会超时。

Not sure what to do.不知道该怎么办。 Is it best practice to seperate these 2 tasks or am I doing something wrong?将这两项任务分开是最佳做法还是我做错了什么?

    let data = null;

module.exports.handler = async (event) => {
  //context.callbackWaitsForEmptyEventLoop = false;
  let client;
  try {
    client = new Redis(
      6379,
      "redis://---.---.ng.0001.use1.cache.amazonaws.com"
    );

client.get(event.token, async (err, result) => {
      if (err) {
        console.error(err);
      } else {
        data = result;
        await client.quit();
      }
    });

    if (data && new Date().getTime() / 1000 - eval(data).timestamp < 30) {

      res.send(`({
        "address": "${token}",
        "price": "${eval(data).price}",
        "timestamp": "${eval(data).timestamp}"
      })`);
    } else {
      getPrice(event); //fetch api data
    }
    ```
   

There a lot of misunderstand in your code.您的代码中存在很多误解。 I'll try to guide you to fix it and understand how to do that correctly.我将尝试指导您修复它并了解如何正确执行此操作。

  1. You are mixing asynchronous and synchronous code in your function.您在 function 中混合了异步和同步代码。
  2. You should use JSON.parse instead of eval to parse the data because eval allows arbitrary code to be executed in your function您应该使用 JSON.parse 而不是 eval 来解析数据,因为 eval 允许在您的 function 中执行任意代码
  3. You're using the res.send to return response to the client instead of callback.您正在使用 res.send 将响应返回给客户端而不是回调。 Remember the usage of res.send is only in express and you're using a lambda and to return the result to client you need to use callback function请记住,res.send 的用法仅在 express 中,您使用的是 lambda 并将结果返回给客户端,您需要使用回调 function

To help you in this task, I completely rewrite your code solving these misundersand.为了帮助您完成这项任务,我完全重写了您的代码以解决这些误解。

const Redis = require('ioredis');

module.exports.handler = async (event, context, callback) => {
  // prefer to use lambda env instead of put directly in the code
  const client = new Redis(
    "REDIS_PORT_ENV",
    "REDIS_HOST_ENV"  
  );

  const data = await client.get(event.token);
  client.quit();
  const parsedData = JSON.parse(data);
  if (parsedDate && new Date().getTime() / 1000 - parsedData.timestamp < 30) {
    callback(null, {
      address: event.token,
      price: parsedData.price,
      timestamp: parsedData.timestamp
    });
  } else {
    const dataFromApi = await getPrice(event);
    callback(null, dataFromApi);
  }
};

There another usage with lambdas that return an object instead of pass a object inside callback, but I think you get the idea and understood your mistakes. lambda 的另一种用法是返回 object 而不是传递 object 内部回调,但我认为你明白了你的想法并理解了你的错误。

Follow the docs about correctly usage of lambda: https://docs.aws.amazon.com/sdk-for-javascript/v2/developer-guide/using-lambda-functions.html遵循有关正确使用 lambda 的文档: https://docs.aws.amazon.com/sdk-for-javascript/v2/developer-guide/using-lambda-functions.html

To undestand more about async and sync in javascript: https://www.freecodecamp.org/news/synchronous-vs-asynchronous-in-javascript/要了解更多关于 javascript 中的异步和同步: https://www.freecodecamp.org/news/synchronous-vs-asynchronous-in-javascript/

JSON.parse x eval: JSON.parse vs. eval() JSON.parse x eval: JSON.parse 与 eval()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 AWS Lambda SSM 调用随机超时 - AWS Lambda SSM calls randomly goes in timeout AWS Lambda 内部轮询器如何管理 SQS API 调用? - How does AWS Lambda internal pollers manage SQS API calls? 递归 AWS Lambda function 调用 - 最佳实践 - Recursive AWS Lambda function calls - Best Practice 为什么我的 function 调用 API 或启动协程返回空值或 null 值? - Why does my function that calls an API or launches a coroutine return an empty or null value? 为什么我的 AWS Lambda Axios 请求外部 API 返回编码字符? - Why is my AWS Lambda Axios request to an external API returning encoded characters? 在 python 中使用 AWS Lambda 向外部 API 发送 Post 请求 - Send Post request to an external API using AWS Lambda in python 为什么在通过 API 网关调用时,Java 中的 AWS Lambda 代码返回“内部服务器错误”? - why does this AWS Lambda code in Java return "internal server error" when invoked via an API gateway? google node api 是否支持部署管理器函数调用? - Does google node api support deployment manager function calls? 跨账户 Lambda 从步骤 Function 调用 - Cross Account Lambda calls from Step Function 为什么 settimeout 在我的 aws lambda 中导致 502? - Why does settimeout cause a 502 in my aws lambda?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM