JBOSS


세션 복제 설정 방법


written by HuscarL


 설명


JBoss는 HTTP 세션 복제와 관련하여 다음과 같은 설정 항목이 있습니다.

-         세션 복제 사용 여부

-         세션 변경 여부(dirty check) 기 준

-         세션 복제 단위

-         세션 복제 시점

-         세션 복제 메시지 전송 방식

 

1) 세션 복제 사용 여부

WAS에서는 각 모듈 별로 분산 혹은 클러스터링 여부를 설정할 수 있도록 하고 있습니다.

특히 웹 어플리케이션의 경우에는 web.xml에서 <distributable/>을 설정해 표준적인 방법으로 클러스터링을 설정합니다.

WEB-INF/web.xml

<web-app>

   <distributable/>

   … …

</web-app>

 

(*) 서버 상에 클러스터링 설정을 잘 했어도 정작 웹 어플리케이션에 이 설정을 하지 않으면 세션 복제는 일어나지 않습니다.

 

2) 세션 변경 여부 기준

JBoss Clustering 세 션 관리자는 HTTP 요청 처리 후 변경된 세션을 클러스터를 구성하는 각 노드로 복제합니다.

그렇다면 세션 관리자는 어떻게 세션이 변경되었는지 알 수 있을까요?

 

가장 쉬운 방법은 프로그램에서 session.setAttribute()를 호출하면 세션이 변경된 것으로 간주하는 것입니다.

UserInfo user = session.getAttribute("user");

// user 정보 변경

session.setAttribute("user", user);

 

JBoss를 비롯한 대부분의 WAS는 이 방법을 지원합니다.

그런데 JBoss에 서 이 방식이 기본설정이 아니므로 이 방식을 사용하기 위해서는 해당 웹어플리케이션의 JBoss Deployment Descriptor에 추가적인 설정이 필요합니다.

 

WEB-INF/jboss-web.xml

<jboss-web>

   <replication-config>

      <replication-trigger>SET</replication-trigger>

      <replication-granularity>SESSION</replication-granularity>

   </replication-config>

</jboss-web>

 

JBoss에서 지원하는 세션 변경 여부 판단 기준은 다음과 같습니다.

SET

setAttribute() 시 세션이 변경된 것으로 간주

SET_AND_NON_PRIMITIVE_GET

setAttribute() 뿐만 아니라 변경 가능한 object에 대한 getAttribute() 시 세션이 변경된 것으로 간주. 디폴트 설정

SET_AND_GET

setAttribute() 뿐만 아니라 getAttribute() 시에도 세션이 변경된 것으로 간주

ACCESS

HTTP 요청이 있을 때 마다 session이 변경된 것으로 간주

 

SET_AND_NON_PRIMITIVE_GET은 개발자가 세션에서 객체를 가져와 변경한 후 setAttribute()를 해주지 않는 경우를 위한 것입니다.

이는 SET_AND_GET과 유사하지만 Integer나 String과 같이 변경 불가능한 객체에 대해서는 변경으로 간주하지 않는다는 차이가 있습니다.

주로 클러스터링을 고려하지 않고 단독 서버 용으로 개발된 어플리케이션을 클러스터 상에 디플로이할 때 사용합니다.

 

(*) 프로그램 상에 위와 같은 문제가 없다면 replication-trigger를 SET으 로 설정하는 것이 가장 좋습니다.

 

3) 세션 복제 단위

변경된 세션을 클러스터상의 각 노드로 복제할 때 가장 단순한 방법은 세션을 통째로 복제하는 것입니다.

하지만 변경된 부분만 복제한다면 전송량을 줄일 수 있어 성능이 향상될 것입니다.

JBoss는 상황에 따라 선택할 수 있도록3가지 복제 단위를 지원합니다.

SESSION

세션을 통째로 복제

ATTRIBUTE

세션에서 변경된 attribute만 을 복제

FIEDLD

attribute object의 변경된 필드만을 복제

 

SESSION à ATTRIBUTE à FIELD 순으로 복제 단위는 더 세분화됩니다. 그런데 복제 단위를 세분화하는데 따르는 오버헤드가 있기 때문에 단순히 세분화할수록 좋은 것은 아닙니다.

 

통상 세션 크기가 5K 이하라면 세션을 통째로 복제하는 것이 가장 효율적입니다.

세션 크기가 그 이상이고 일부 attribute만 변경이 잦은 경우라면 ATTRIBUTE를 선택할 수 있습니다.

세션이 아주 크고, attrribute의 특정 필드만 변경이 잦은 경우라면 FIELD를 선택할 수 있습니다.

주의할 점은 그 변경되는 attribute 또는 필드가 세션 크기의 대부분을 차지한다면 전송량 자체가 줄지 않으므로 전혀 이점이 없겠죠.

 

WEB-INF/jboss-web.xml

<jboss-web>

   <replication-config>

      <replication-trigger>SET</replication-trigger>

      <replication-granularity>SESSION</replication-granularity>

   </replication-config>

</jboss-web>

 

 

4) 세션 복제 시점

JBoss는 세션의 변경 사항을 즉시 (instant) 또는 일정 간격 (interval)으로 복제할 수 있습니다.

기본값은 instant로 Tomcat 서비스에 설정되어 있습니다.

 

deploy/jboss-web.deployer/META-INF/jboss-service.xml

<attribute name="SnapshotMode">instant</attribute>

<attribute name="SnapshotInterval">2000</attribute>

 

SnapshotMode를 interval로 설정할 경우에는 추가적으로 SnapshotInterval 값으로 복제 주기를 ms 단위로 설정할 수 있습니다.

만약 주기를 30초 로 잡으면 그 사이에 장애가 발생할 경우 변경된 세션 정보를 잃어버리게 됩니다.

 

(*) 특별히 세션 정보를 잃어버려도 되는 상황이 아니라면 instant를 그대로 두는게 안전합니다.

 

5) 세션 복제 메시지 전송 방식

세션이 변경되어 클러스터상의 각 노드로 세션을 전송할 때에는 각 노드로부터 전송이 완료되었다는 ACK를 받을 때까지 기다리는 동기 방식 (REPL_SYNC) 과 그냥 큐에 넣어두고 별도 쓰레드에서 전송을 처리하는 비동기 방식 (REPL_ASYNC)을 선택할 수 있습니다.

 

기본값은 REPL_ASYNC로 Tomcat 클러스터 서비스에 설정되어 있습니다.

deploy/jboss-web-cluster.sar/META-INF/jboss-service.xml

<attribute name="CacheMode">REPL_ASYNC</attribute>

 

ShapshotMode와 CacheMode를 함께 생각해보면 기본값 조합에서는 HTTP 요청을 처리한 후 세션이 변경되었으면 바로 각 노드로 세션을 복제하도록 메시지를 큐에 넣고 Servlet/JSP 수 행을 끝냅니다. 결국 클라이언트에게 응답이 간 시점에 세션 복제가 완료되었는지 장담할 수 없습니다.

만약 세션 복제가 이루어지기 전에 클라이언트가 다시 HTTP 요청을 했는데, 이 HTTP 요청이 다른 노드로 전달될 경우에는, 예 전 세션을 가지고 처리하는 문제가 발생할 수 있습니다.

이 때문에 JBoss 클러스터링 기본 설정을 그대로 사용할 경우에는 반드시 Sticky 로 드 밸런싱을 설정해 요청이 계속 세션이 생성된 노드로 가도록 해야 합니다.

 

동기 방식 (REPL_SYNC)을 선택했다면 모든 노드로 세션 복제를 완료한 후에야 Servlet/JSP 수행이 끝나므로 위의 문제가 발생하지 않습니다.




방문 해주셔서 감사합니다. 로그인 없이 가능한

아래 하트♥공감 버튼을 꾹 눌러주시면 감사하겠습니다! 





+ Recent posts