有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

amazon web服务AWS Lambda(Java)调用错误的对象实例

我对AWS Lambda调用有一个不寻常的问题,在搜索时没有找到太多关于这一点的信息。我希望在座的人对Java垃圾收集器和/或AWS lambda容器有更深入的了解

我已经创建了一个自定义打印流来捕获系统中的打印输出。我们需要一个完整的系统。犯错误目的是通过记录器记录这些打印输出,为消息添加有用的信息

自定义打印流。在第一次调用之后,每次调用都会触发写操作。它仍然使用第一次调用中的对象。这意味着当我使用变量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函数时,会出现此问题,有关跟踪日志记录事件,请参阅hashcode、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类调用logging时会出现问题,我尝试在程序完成后将CustomPrintStream和logger设置为null,并从super类手动调用finalize方法,但这不会改变任何事情

我希望打印输出使用logger对象中的CustomPrintStream进行当前调用

我很感激你的回答


共 (1) 个答案

  1. # 1 楼答案

    听起来像是在CustomPrintStream上下文中创建static。由于container reuse在AWS Lambda中的工作方式,静态定义的对象将在调用期间保持不变