JCR 세션이 AEM 인스턴스에서 누출되는지 확인하고 분석합니다.
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 개체로 이동합니다.
- 타임스탬프가 더 늦거나 더 높은 ID 번호가 나열된
[
Ctrl]
+ 일부 를 클릭하여 새 브라우저 탭에서 SessionStatistics 개체를 엽니다. 예를 들어, 다음 예제는 ID가 입니다. 12105:org.apache.jackrabbit.oak "SessionStatistics" "admin@session-12105@Aug 10, 2020 7:03:25 PM" {id=287}
.- ID가 높을수록 마지막 AEM을 다시 시작한 후 세션이 더 나중에 생성됩니다.
- 해당 세션을 연 코드를 보여주는 스택 추적을 검토합니다.
- 스택에서 애플리케이션 Java 패키지를 검색합니다. 코드가 애플리케이션의 일부인 경우 다음 섹션을 참조하십시오.
III. 세션 누출 해결
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();
요청이 처리된 후 해당 문제 해결 및 세션이 자동으로 닫힙니다.