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 を超える場合は、セッションリークがあります。
II. セッションが漏洩しているコードの特定
セッションリークが見つかった場合は、次の手順に従って、その原因を特定します。
- SessionStatistics オブジェクトまでページを下にスクロールします。
- Ctrl キーを押しながら
[キーを押し]ID 番号が新しく表示される SessionStatistics オブジェクトの一部をクリックして、新しいブラウザータブで開きます。 例えば、以下の 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 を介して取得した Session オブジェクトと ResourceResolver オブジェクトは、アプリケーションで閉じないでください。 例:
slingRequest.getResourceResolver().adaptTo(Session.class);
//Or
workflowSession.getSession();
そのリゾルバーとセッションは、リクエストが処理されると、自動的に閉じられます。