2017-06-07 32 views
1

我正试图找到一个非常具体的问题的答案。试图通过documentation但迄今没有运气。AWS Java Lambda局部变量与对象变量

想象这段代码

@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<>(); 
} 

在这里,我在field变量存储orderIdstoreId。这个可以吗?我不确定AWS是否会缓存该函数,从而缓存字段变量,或者是否会为每个请求启动一个新的Java对象。如果它的一个新对象,然后存储在字段变量是好的,但不确定。

回答

2

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 
0

强烈不建议。

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

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