c - 与 Node 和 Node-gyp 一起使用的 AWS Lambda 上出现奇怪的 "memory"行为

标签 c node.js amazon-web-services aws-lambda

我有一个用 NodeJS 编写的 AWS Lambda,调用过程非常简单

NODEJS -> NodeModule(CPP) -> Extern C Function,此设置是使用 node-gyp 编译的。 您可以在 https://drive.google.com/open?id=0B-2d-CuY5fkwS3lwdE96R1V6NEk 处查看完整代码。

CPP Node 模块调用 C 中的一个函数,该函数运行一个循环。并增加两个变量,一个在 C 函数范围内,另一个在 C 代码主范围内。

当您在本地运行此代码时。循环递增,两个变量都达到 11,正如您运行循环的预期一样。但是,当您在 AWS Lambda 中运行相同的代码时,每次调用都会有某种“内存”。而一般作用域中未重置的变量正在以 11、22、33 等的倍数增加。

重复一遍,这在本地永远不会发生,两个变量始终为 11。 你可以通过运行来构建 1.node-gyp清理配置构建 2.node app.js(用于本地运行)

Index.js 适用于 AWS Lambda

我真的无法解释这种行为? Lambda 是否提供某种上下文或某种“内存”或缓存?

我为此制作了一个开放 API 网关。 (随时刷新并查看“内存”的运作)。

https://koj2yva6z9.execute-api.us-east-1.amazonaws.com/dev/testLambdaCache

此行为有时不一致,有时计数会重置。或者您可以通过上传新的 AWS lambda 代码来重置。

对这种奇怪行为的任何想法表示赞赏。

app.js(用于本地测试)

var addon = require('./build/Release/addon');
console.log(addon.testCache());
console.log(" addon method completed");

index.js(在 lambda 中使用)

console.log('Loading function');

exports.handler = (event, context, callback) => {

    var addon = require('./build/Release/addon');
    var returnvalue=addon.testCache();
    console.log(returnvalue);
    console.log(" addon method completed");
    callback(null, "success::"+returnvalue);
}

base.cc(C 代码的包装)

#include <node.h>
#include <iostream>
#include <stdlib.h>
#include<string>
#include<cstring>

using namespace std;

extern "C" char* testCache();

namespace demo {

    using v8::FunctionCallbackInfo;
    using v8::HandleScope;
    using v8::Isolate;
    using v8::Local;
    using v8::Object;
    using v8::String;
    using v8::Value;
    using v8::Exception;

    void Method(const FunctionCallbackInfo<Value>& args) {
        Isolate* isolate = args.GetIsolate();
        cout << "C++ method started\n";
        char *returnStrings=NULL;
        returnStrings= testCache();
        args.GetReturnValue().Set(String::NewFromUtf8(isolate,  returnStrings ));
    }

    void init(Local<Object> exports) {
        NODE_SET_METHOD(exports, "testCache", Method);
    }

    NODE_MODULE(addon, init)

}  

decoder.c(运行循环的 C 代码)

int tmpCounter=0;


char* testCache()
{
    int counter=0;
    printf("Local counter --> %d  Global Counter --> %d\n",counter,tmpCounter); 
    for(int i=0;i <10; i++)
    {
        counter = counter +1;
        tmpCounter = tmpCounter +1;
        //sleep(1);
    }
    printf("Local counter --> %d  Global Counter --> %d\n",counter,tmpCounter); 

    counter=counter+1;
    tmpCounter=tmpCounter+1;

    char strCounter[100];
    char strTmpCounter[100];
    snprintf(strCounter, 16, "%d", counter);

    snprintf(strTmpCounter, 16, "%d", tmpCounter);

    char *returnString=NULL;
    returnString=malloc(1000);

    strcat(returnString, "Count:");
    strcat(returnString, strCounter);
    strcat(returnString, " TmpCount:");
    strcat(returnString, strTmpCounter);
    strcat(returnString, "\0");
    printf("%s\n",returnString);
    fflush(stdout);
    return returnString;

}

最佳答案

is there some sort of context or some sort of "memory" or caching that is available with Lambda?

我不会说它是“可用的”,因为它是可预测的或一致的,因为你不应该围绕它进行设计,但是,是的,存在容器重用。

要查看实际效果:

创建一个 uuid、随机数或类似的东西,并将其存储在处理程序外部的全局变量中。然后,在处理程序内记录它。您将看到相同的进程或进程组(由 uuid 标识)可能(但不一定)处理时间上接近的后续请求。

Let’s say your function finishes, and some time passes, then you call it again. Lambda may create a new container all over again [...]

However, if you haven’t changed the code and not too much time has gone by, Lambda may reuse the previous container. This offers some performance advantages to both parties: Lambda gets to skip the nodejs language initialization, and you get to skip initialization in your code. Files that you wrote to /tmp last time around will still be there if the sandbox gets reused.

https://aws.amazon.com/blogs/compute/container-reuse-in-lambda/

关于c - 与 Node 和 Node-gyp 一起使用的 AWS Lambda 上出现奇怪的 "memory"行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37987271/

相关文章:

c - 防止 "warning: implicit declaration of function ' setlinebuf'...”

c - 对于此示例,我的 C 中双指针/指针的逻辑是否正确

mysql - 如何将 mysql.h 和 my_global.h 包含到 Makefile.am 中?

node.js - 我正在尝试从 DynamoDB 表获取各个属性,并在回调之前将它们转换为变量

php - 使用亚马逊 MWS 时我的 Feed 应该是什么样子?

amazon-web-services - AWS ElastiCache redis 和 maxmemory

c - 如何将 struct * 作为函数的参数

node.js - Node.js 的 Connect、Express 和 "middleware"是什么?

javascript - nodejs http请求卡住

node.js - 使用 Lambda 定期清除 Redis 缓存