检查并确定AEM 6.x应用程序JCR会话泄露的原因。
检查您的AEM 6.x应用程序是否存在JCR会话泄露并跟踪源。
环境
AEM 6.4,6.5
I.检查是否存在会话泄露
二、识别泄露会话的代码
如果发现会话泄露,请按照以下步骤查找导致会话泄露的原因。
[
Ctrl]
+单击部分 列出了时间戳或更高的ID编号。 例如,下面的ID为12105:org.apache.jackrabbit.oak "SessionStatistics" "admin@session-12105@Aug 10, 2020 7:03:25 PM" {id=287}
。三、修复会话泄露
要防止和修复JCR会话泄露,请执行以下操作:
关闭会话对象:
下面的代码使会话保持打开状态:
try {
Session session = repository.loginAdministrative(null);
Node node = session.getNode("/content/we-retail");
log.info("Node: " + node.getPath());
} catch (RepositoryException re) {
log.error(re.getMessage(), re);
}
*注意:*除了关闭会话之外,此代码还会调用repository.loginAdministrative来打开会话。 出于安全原因,AEM的更高版本已弃用这种打开会话的方式。
要关闭会话,您可以使用try/finally代码块封装代码并调用session.logout():
Session session = null;
try {
session = repository.loginAdministrative(null);
// use session
} catch (RepositoryException re) {
log.error(re.getMessage(), re);
} finally {
if (session != null && session.isLive()) {
session.logout();
}
}
创建会话或共享会话时要小心。 跨对象共享会话时,将更难跟踪会话打开的位置以及必须关闭会话的时间。 此外,绝不能跨Java Threads共享会话。
关闭ResourceResolver对象:
下面的代码会让ResourceResolver处于打开状态:
try{
ResourceResolver resourceResolver = resourceFactory.getServiceResourceResolver(paramMap);
Resource resource = resourceResolver.getResource("/content/we-retail");
log.info("Resource: " + res.getPath());
} catch(Exception e){
log.error(e.getMessage());
}
要关闭resourceResolver,请使用try/finally代码块封装代码并调用resourceResolver.close():
try{
ResourceResolver resourceResolver = resourceFactory.getServiceResourceResolver(paramMap);
// use ResourceResolver
} catch (Exception e) {
log.error(e.getMessage());
} finally {
if(resourceResolver != null && resourceResolver.isLive()) {
resourceResolver.close();
}
}
重要说明
通过SlingRequest或WorkflowSession获取的会话和ResourceResolver对象,不应由应用程序关闭。 例如:
slingRequest.getResourceResolver().adaptTo(Session.class);
//Or
workflowSession.getSession();
该解析程序和会话将在处理完请求后自动关闭。