简体   繁体   English

AWS Lambda(Java)调用对象的错误实例

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

I have a unusual problem with AWS Lambda invocations, did not find much about this when searching. 我对AWS Lambda调用有一个不寻常的问题,在搜索时没有发现太多有关此的信息。 I'm hoping someone here has a deeper understanding of Java garbage collector and/or AWS lambda containers. 我希望这里的人对Java垃圾收集器和/或AWS Lambda容器有更深入的了解。

I've created a custom PrintStream to catch printouts from System.out and System.err. 我创建了一个自定义PrintStream来捕获System.out和System.err中的打印输出。 The purpose is to log these printouts through the logger to add useful some more useful information to the messages. 目的是通过记录器记录这些打印输出,以向消息中添加有用的一些更有用的信息。

CustomPrintStream.write is triggered on every invocation after the first one it still uses the object from the first invocation. 在第一次调用后,每次调用都会触发CustomPrintStream.write,它仍将使用第一次调用中的对象。 Which means that when the variable timeWhenFunctionStarted i used it contains the value from the first invokation and the time elapsed is incorrect. 这意味着,当我使用变量timeWhenFunctionStarted时,它包含第一次调用的值,并且经过的时间不正确。

I've added printout of the objects hashcode to better illustrate this problem. 我添加了对象哈希码的打印输出,以更好地说明此问题。

Here are the logs 这是日志

During the first invocation (cold start) everything is as expected, consistent ms and same hashcode: 在第一次调用(冷启动)期间,所有内容均与预期一致,一致的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

The issue occurs when the lambda function is invoked again in the same container, see hashcode, requestid and ms for trace logging event: 当在同一容器中再次调用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 

Logging class: 记录类别:

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

CustomLogger is called from Lambda function handler where issue is not present: 从不存在问题的Lambda函数处理程序中调用CustomLogger:

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

The problem occurs when logging is called from CustomPrintStream class, I've tried setting CustomPrintStream and the logger to null after program completion and manually calling the finalize method from the super class but that does not change anything. 当从CustomPrintStream类调用日志记录时会出现问题,我尝试在程序完成后将CustomPrintStream和logger设置为null,并从超类手动调用finalize方法,但这并没有改变。

What i want to happen is for the printouts to use the CustomPrintStream in the logger object for the current invocation. 我想要发生的是打印输出使用logger对象中的CustomPrintStream进行当前调用。

I'm grateful for answers. 我很感谢答案。

It sounds like you are creating CustomPrintStream in a static context. 听起来您是在static上下文中创建CustomPrintStream Due to the way container reuse works in AWS Lambda, your statically defined objects will persist across invocations. 由于容器重用在AWS Lambda中的工作方式,因此静态定义的对象将在调用之间持久存在。

Solved the issue, kind of at least. 至少解决了这个问题。 Moved CustomPrintStream out of CustomLogger class. 将CustomPrintStream从CustomLogger类移出。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM