簡體   English   中英

AWS Lambda(Java)調用對象的錯誤實例

[英]AWS Lambda (Java) invoking wrong instance of Object

我對AWS Lambda調用有一個不尋常的問題,在搜索時沒有發現太多有關此的信息。 我希望這里的人對Java垃圾收集器和/或AWS Lambda容器有更深入的了解。

我創建了一個自定義PrintStream來捕獲System.out和System.err中的打印輸出。 目的是通過記錄器記錄這些打印輸出,以向消息中添加有用的一些更有用的信息。

在第一次調用后,每次調用都會觸發CustomPrintStream.write,它仍將使用第一次調用中的對象。 這意味着,當我使用變量timeWhenFunctionStarted時,它包含第一次調用的值,並且經過的時間不正確。

我添加了對象哈希碼的打印輸出,以更好地說明此問題。

這是日志

在第一次調用(冷啟動)期間,所有內容均與預期一致,一致的ms和相同的哈希碼:

START RequestId: {requestid1} Version: $LATEST
2019-01-09 12:37:09.175 [INFO]  {requestid1} START  (1 ms)      hashcode: 601008104 //other stuff
2019-01-09 12:37:09.193 [DEBUG] {requestid1}        (18 ms)     hashcode: 601008104 //other stuff
2019-01-09 12:37:09.213 [INFO]  {requestid1}        (38 ms)     hashcode: 601008104 //other stuff
2019-01-09 12:37:13.813 [TRACE] {requestid1}        (4638 ms)   hashcode: 601008104 //other stuff
2019-01-09 12:37:16.143 [INFO]  {requestid1}        (6968 ms)   hashcode: 601008104 //other stuff
2019-01-09 12:37:16.143 [INFO]  {requestid1} END    (6968 ms)   hashcode: 601008104 //other stuff
END RequestId: {requestid1}
REPORT RequestId: {requestid1} Duration: 7207.15 ms Billed Duration: 7300 ms Memory Size: 512 MB Max Memory Used: 113 MB

當在同一容器中再次調用lambda函數時,會發生此問題,有關跟蹤日志記錄事件,請參見哈希碼,requestid和ms:

START RequestId: {requestid2} Version: $LATEST
2019-01-09 12:37:29.717 [INFO]  {requestid2} START  (0 ms)      hashcode: 2117173674 //other stuff
2019-01-09 12:37:29.717 [DEBUG] {requestid2}        (1 ms)      hashcode: 2117173674 //other stuff
2019-01-09 12:37:29.718 [INFO]  {requestid2}        (1 ms)      hashcode: 2117173674 //other stuff
2019-01-09 12:37:29.815 [TRACE] {requestid1}        (20640 ms)  hashcode: 601008104  //other stuff
2019-01-09 12:37:30.075 [INFO]  {requestid2}        (358 ms)    hashcode: 2117173674 //other stuff
2019-01-09 12:37:30.075 [INFO]  {requestid2} END    (358 ms)    hashcode: 2117173674 //other stuff
END RequestId: {requestid2}
REPORT RequestId: {requestid2} Duration: 358.78 ms Billed Duration: 400 ms Memory Size: 512 MB Max Memory Used: 116 MB 

記錄類別:

public class CustomLogger {

    //Constructor setting System out to object of class customPrintStream
    public CustomLogger(...) {
        //other stuff
        this.logger = context.getLogger();
        this.baosSystemOut = new ByteArrayOutputStream();
        this.customPrintStreamObject= new customPrintStream(baosSystemOut);
        System.setOut(customPrintStreamObject);
    }

    //Every logged message goes through here.
    private void logMessages(String[] messages, String logLevel) {
        //other stuff
        String formatedMessage = ... System.currentTimeMillis() - timeWhenFunctionStarted ... System.hashcode(this) ...;
        LOGGER.log(formatedMessage);
    }

    //called from CustomPrintStream class and from Lambda function handler, same for TRACE, DEBUG, INFO, WARN and ERROR.
    public class logTRACE(String... messages){
        //other stuff
        logMessages(messages, "TRACE");
    }

    //private class to catch logging
    private class CustomPrintStream extends PrintStream {
        //other stuff
        @Override
        public void write(byte[] buf, int off, int len) {
            //other stuff
            logTRACE(message);
        }
    }
}

從不存在問題的Lambda函數處理程序中調用CustomLogger:

//other stuff
CustomLogger logger = new CustomLogger(...);
logger.logINFO(...);

當從CustomPrintStream類調用日志記錄時會出現問題,我嘗試在程序完成后將CustomPrintStream和logger設置為null,並從超類手動調用finalize方法,但這並沒有改變。

我想要發生的是打印輸出使用logger對象中的CustomPrintStream進行當前調用。

我很感謝答案。

聽起來您是在static上下文中創建CustomPrintStream 由於容器重用在AWS Lambda中的工作方式,因此靜態定義的對象將在調用之間持久存在。

至少解決了這個問題。 將CustomPrintStream從CustomLogger類移出。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM