检查并分析AEM实例中是否存在JCR会话泄露
检查并确定AEM 6.x应用程序JCR会话泄露的原因。
描述 description
检查您的AEM 6.x应用程序是否存在JCR会话泄露并跟踪源。
环境
AEM 6.4,6.5
分辨率 resolution
I.检查是否存在会话泄露
- 转到 http://host:port/system/console/jmx 并以管理员身份登录。
- 使用浏览器的搜索功能查找页面上出现的所有SessionStatistics对象。
- 如果找到的对象超过500个,则存在会话泄露。
二、识别泄露会话的代码
如果发现会话泄露,请按照以下步骤查找导致会话泄露的原因。
- 向下滚动该页至SessionStatistics对象。
- 在新的浏览器选项卡中打开一些SessionStatistics对象,方法是
[
Ctrl]
+单击部分 列出了时间戳或更高的ID编号。 例如,下面的ID为 12105:org.apache.jackrabbit.oak "SessionStatistics" "admin@session-12105@Aug 10, 2020 7:03:25 PM" {id=287}
。- ID编号越高,上次重新启动AEM后创建的会话就越新。
- 查看栈栈跟踪,以显示打开了这些会话的代码。
- 在栈栈中搜索应用程序java包。 如果代码是应用程序的一部分,请参阅下一部分。
三、修复会话泄露
要防止和修复JCR会话泄露,请执行以下操作:
- 如果您打开 javax.jcr.Session 然后始终通过以下方式将其关闭 Session.logout()
- 如果您打开 org.apache.sling.api.resource.ResourceResolver 然后始终通过以下方式将其关闭 ResourceResolver.close()
关闭会话对象:
下面的代码使会话保持打开状态:
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();
该解析程序和会话将在处理完请求后自动关闭。
recommendation-more-help
3d58f420-19b5-47a0-a122-5c9dab55ec7f