英文:
Reuse SSLContext object in AWS Lambda Environment
问题
以下是翻译好的内容:
我有一个 JAVA 8 的 AWS Lambda 函数,在容器首次启动时进行一些相当昂贵的设置。它必须进行调用以获取各种凭据/证书。我希望可以缓存这个设置(其输出是用于调用另一个 API 的 SSLContext 对象)。
我以前没有这样做过,我找不到答案的问题是:
在 Lambda 容器存活期间反复重用 SSLContext 对象会有任何问题吗?这可能是 15 分钟、5 小时、2 天等等,只要有流量通过它,它就会保持活动状态。
所有的凭据都不会改变,而且 SSLContext 对象在所有调用之间都将是相同的。
SSLContext 对象有 TTL 吗?创建 SSLContext 的代码相当模板化。在进行了获取证书/凭据的昂贵操作后,会调用此方法,并且我希望缓存这个 SSLContext 对象:
public SSLContext getContext(){
KeyStore clientStore = KeyStore.getInstance(KEY_INSTANCE);
keyStoreInputstream = //获取流
clientStore.load(keyStoreInputstream, caCertCred.toCharArray());
KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
kmf.init(clientStore, KEY.toCharArray());
KeyManager[] kms = kmf.getKeyManagers();
trustStoreInputStream = //获取流
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;
}
英文:
I have a JAVA 8 AWS lambda function that has some pretty expensive setup when the container is first spun up. It must make calls to pull various credentials/cacerts. I would like to cache this set up (the output of which is an SSLContext object that is used for making calls to another api).
I have not had to do this before, and my question that I cannot seem to find an answer for is this:
Are there any issues reusing the SSLContext object over and over again while the Lambda Container is alive? this could be 15 minutes or 5 hours, or 2 days, etc.. as long as there is traffic coming through it, it will be alive.
None of the credentials will change, and the SSLContext object would be identical between all invocations.
Do SSLContext objects have a TTL? The code to create the SSLConext is fairly boilerplate. This method is called after I have done the expensive pulls to get the certs/cred and I want to cache this SSLContext object:
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;
}
答案1
得分: 0
简短回答:使用类级变量。
在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();
// 进行一些操作
if(sslContext == null) {
// 这表示需要初始化SSLContext - 可能是一个新的容器
initSslContext();
} else {
// 这表示SSLContext已经初始化 - 直接使用它
}
// 使用SSLContext
}
private void initSslContext() {
// 注意:您需要在此处创建KeyStore、KeyManagerFactory
// 并重新初始化SSLContext,因为它为null
}
}
注意:
通常,全局变量可能会有一些缺点,但我认为在您的情况下不会引发任何问题。您可以观看以下视频,真正理解在AWS Lambda中如何使用全局变量。
https://www.youtube.com/watch?v=-P7oB8NQpiI
英文:
The short answer: Use a class-level variable.
In AWS Lambda, class level variables are "global" variables. So if you declare a variable outside the handleRequest(...)
method, the Lambda container will keep that variable initialized with the same value. When the lambda function executes again, you just have to reuse the variable as it is.
Here's an example of how it works:
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
}
}
Note:
Usually, global variables have some downside but I think in your case, it wouldn't create any issues. You can watch the following video to really understand how global variables work in AWS Lambda.
https://www.youtube.com/watch?v=-P7oB8NQpiI
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论