AWS Java Lambda局部变量vs对象变量

时间:2017-06-07 22:14:59

标签: java amazon-web-services aws-lambda

我试图找到一个非常具体的问题的答案。试图通过documentation,但到目前为止没有运气。

想象一下这段代码

@Override
public void handleRequest(InputStream input, OutputStream output, Context context) throws IOException {
    Request request = parseRequest(input);

    List<String> validationErrors = validate(request);

    if (validationErrors.size() == 0){
        ordersManager.getOrderStatusForStore(orderId, storeId);
    } else {
        generateBadRequestResponse(output, "Invalid Request", null);
    }
}

private List<String> validate(Request request) {
    orderId = request.getPathParameters().get(PATH_PARAM_ORDER_ID);
    programId = request.getPathParameters().get(PATH_PARAM_STORE_ID);
    return new ArrayList<>();
}

在这里,我将orderIdstoreId存储在field个变量中。这个可以吗?我不确定AWS是否会缓存此函数并因此缓存字段变量,或者它是否会为每个请求启动一个新的Java对象。如果它是一个新对象,那么存储在字段变量中很好但不确定。

2 个答案:

答案 0 :(得分:6)

AWS将启动JVM并在第一个请求时实例化您的代码实例。 AWS具有未记录的停机时间,如果您在此时间限制内未再次调用Lambda,则会关闭JVM。您会注意到这些初始请求可能会花费更长的时间,但是一旦您的功能“预热”,它就会快得多。

因此,要直接回答您的问题,如果下一个请求足够快,您的实例将被重用。否则,将会出现一个新实例。

一个简单的Lambda函数可以说明这一点:

/**
 * A Lambda handler to see where this runs and when instances are reused.
 */
public class LambdaStatus {

    private String hostname;
    private AtomicLong counter;

    public LambdaStatus() throws UnknownHostException {
        this.counter = new AtomicLong(0L);
        this.hostname = InetAddress.getLocalHost().getCanonicalHostName();
    }

    public void handle(Context context) {
        counter.getAndIncrement();
        context.getLogger().log("hostname=" + hostname + ",counter=" + counter.get());
    }
}

调用上述日志。

22:49:20   hostname=ip-10-12-169-156.ec2.internal,counter=1
22:49:27   hostname=ip-10-12-169-156.ec2.internal,counter=2
22:49:39   hostname=ip-10-12-169-156.ec2.internal,counter=3
01:19:05   hostname=ip-10-33-101-18.ec2.internal,counter=1

答案 1 :(得分:0)

强烈不推荐。

多次调用可能使用相同的Lambda函数实例,这将破坏您当前的功能。

您需要确保您的实例变量是线程安全的,并且在涉及Lambda时可以由多个线程访问。将实例变量写入初始化限制 - 仅限一次。