在AWS Lambda环境中重用SSLContext对象

问题描述

我有一个JAVA 8 AWS lambda函数,该函数在首次启动容器时会进行一些非常昂贵的设置。它必须进行调用提取各种凭证/证书。我想缓存此设置(其输出是用于调用一个api的SSLContext对象)。

我以前不必这样做,而我似乎找不到答案的问题是:

在Lambda容器处于活动状态时,是否有重复使用SSLContext对象的问题?这可能是15分钟或5个小时,或2天等。只要有流量通过,它就会一直存在。

所有凭据都不会更改,并且所有调用间的SSLContext对象都是相同的。

SSLContext对象是否具有TTL?创建SSLConext的代码相当简单。在完成昂贵的提取以获得证书/信条并且要缓存此SSLContext对象之后,将调用方法

public SSLContext getContext(){
        KeyStore clientStore = KeyStore.getInstance(KEY_INSTANCE);
        keyStoreInputstream = //GET STREAM
        clientStore.load(keyStoreInputstream,caCertCred.tochararray());

        KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
        kmf.init(clientStore,KEY.tochararray());
        KeyManager[] kms = kmf.getKeyManagers();

        trustStoreInputStream =  //GET STREAM
        KeyStore trustStore = KeyStore.getInstance(TRUST_INSTANCE);
        trustStore.load(trustStoreInputStream,caCertCred.tochararray());

        TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
        tmf.init(trustStore);
        TrustManager[] tms = tmf.getTrustManagers();

        SSLContext sslContext = SSLContext.getInstance("TLS");
        sslContext.init(kms,tms,new SecureRandom());
        return sslContext;

}

解决方法

简短的答案:使用类级变量。

在AWS Lambda中,类级别变量是“全局”变量。因此,如果在handleRequest(...)方法外部声明变量,则Lambda容器将使该变量使用相同的值进行初始化。当lambda函数再次执行时,您只需按原样重用该变量即可。

以下是其工作方式的示例:

public class LambdaExample implements RequestStreamHandler {

    private LambdaLogger logger;
    private SSLContext sslContext;

    @Override
    public void handleRequest(InputStream input,OutputStream output,Context context) throws IOException {
        logger = context.getLogger();

        // do some work


        if(sslContext == null) {
            // this means SSLContext needs to be initialized - probably a new container
            initSslContext();
        } else {
            // this means SSLContext is already initialized - just use it as it is
        }

        // use SSLContext
    }

    private void initSslContext() {
        // note: you need to create the KeyStore,KeyManagerFactory
        //  and re-initialize the SSLContext here because it's null
    }
}

注意:
通常,全局变量有一些缺点,但是我认为在您的情况下,它不会造成任何问题。您可以观看以下视频,以真正了解全局变量如何在AWS Lambda中工作。
https://www.youtube.com/watch?v=-P7oB8NQpiI