檢查並分析AEM執行個體中是否有JCR工作階段洩漏

檢查並識別AEM 6.x應用程式JCR工作階段洩漏的原因。

說明 description

檢查您的AEM 6.x應用程式是否有JCR工作階段洩漏並追蹤來源。

環境

AEM 6.4、6.5

解析度 resolution

I.檢查是否有工作階段洩漏

  1. 前往 http://host:port/system/console/jmx 並以管理員身分登入。
  2. 使用瀏覽器的搜尋功能,尋找頁面上所有出現的SessionStatistics物件。
  3. 如果您發現超過500個,則會出現工作階段洩漏。

II. 識別洩露工作階段的程式碼

如果您發現工作階段洩漏,請依照下列步驟尋找原因。

  1. 向下捲動頁面至「階段作業統計值」物件。
  2. 在新的瀏覽器標籤中開啟部分SessionStatistics物件,方法是​ [Ctrl] +按一下某些具有更新的時間戳記或列出更高識別碼編號的。  例如,下方的ID為
  3. 12105:org.apache.jackrabbit.oak "SessionStatistics" "admin@session-12105@Aug 10, 2020 7:03:25 PM" {id=287}
  4. ID編號越高,上次重新啟動AEM後建立工作階段的日期越晚。
  5. 檢閱棧疊追蹤,顯示哪些程式碼開啟了這些工作階段。
  6. 在棧疊中搜尋應用程式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