2017-06-07 58 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時可以由多個線程訪問。限制你的實例變量寫入初始化 - 一次。