我试图找到一个非常具体的问题的答案。试图通过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<>();
}
在这里,我将orderId
和storeId
存储在field
个变量中。这个可以吗?我不确定AWS是否会缓存此函数并因此缓存字段变量,或者它是否会为每个请求启动一个新的Java对象。如果它是一个新对象,那么存储在字段变量中很好但不确定。
答案 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时可以由多个线程访问。将实例变量写入初始化限制 - 仅限一次。