/playce-dolly

Primary LanguageJavaApache License 2.0Apache-2.0

playce-dolly

Playce-Dolly는 WAS에 비종속적인 세션 클러스터링 솔루션으로 현재 Apache Tomcat 6/7, JBoss EAP 6, WebLogic 11이 지원 가능하며 추후 Jeus, WebSphere등 다양한 WAS로도 지원을 확대할 계획이다.

  1. Playce-Dolly의 특징

    • 이기종 WAS 간의 세션 클러스터링이 가능할 뿐만 아니라 기존 웹 애플리케이션의 수정이 전혀 필요하지 않다.
    • 세션 클러스터링을 위한 캐시 서버로 JBoss Data Grid(Infinispan)과 Couchbase를 지원하고 있으며 추후 Redis를 추가적으로 지원할 계획이다.
    • 캐시 서버 구축에 부담이 있다면 Infinispan을 WAS 구동 시 내장되어 동작하도록 Embedded 모드로 동작시키거나, 별도의 Standalone Application으로 동작시킬 수 있다.
    • 순수 서버사이드 SSO(Single Sign On) 기능을 지원하고 있어 에어전트 설치 없이 여러 도메인 간 로그인 상태를 유지시킬 수 있다.
    • 캐시 서버의 CPU, Memory 모니터링과 세션 데이터 조회 및 통계정보를 확인할 수 있는 웹 애플리케이션을 제공한다.
  2. Playce-Dolly의 설치

    • mvn install을 수행하게 되면 playce-dolly/core/target 디렉토리에 core-1.1.0-bin.zip 파일이 생성되며, 해당 파일을 설치하고자 하는 서버로 복사한다.
    • core-1.1.0-bin.zip 파일을 압축 해제하게 되면 dolly-agent 라는 디렉토리가 생성되고, 하위에 dolly.properties 파일 및 lib 디렉토리가 존재하며 lib 디렉토리 안에 관련 라이브러리 파일들이 존재한다.
    • dolly.properties 파일에는 Playce Dolly 관련 설정이 포함되며, 아래의 각 항목을 용도에 맞게 수정한다.
  3. dolly.properties 수정

    • dolly.verbose : Verbosity 여부
    • dolly.session.timeout : 세션 만료 시간 설정(분)
    • dolly.client.type : Infispan, Couchbase 등 세션 서버 타입
    • dolly.use.infinispan.embedded : Infinispan Embedded 동작 여부
    • dolly.hotrod.host : Infinispan Embedded 시 사용될 Bind Address 및 Port
    • dolly.jgroups.xxx : Infinispan Embedded 시 사용될 Clustering 설정(jgroups)
    • dolly.enableSSO : SSO 사용 여부
    • dolly.sso.domain.list : SSO 사용 대상 도메인 목록
    • dolly.read.session.local.first : 세션 데이터를 로컬 세션에서 먼저 조회할지 여부 (기본 false)
    • dolly.sso.parameter.key : SSO 사용 시 다른 도메인에 Session ID를 넘겨줄 때 사용하는 Query Parameter Key
    • dolly.session.listener.class : HttpSessionListener를 구현한 클래스를 사용하는 경우 sessionDestroyed() 내의 로직에 의해 만료 대상 세션 데이터가 다시 세션서버로 복제되는 현상이 있다. HttpSessionListener 구현 클래스를 명사하면 sessionDestroyed()시 명시적으로 세션 서버에서 세션 데이터를 삭제한다.
    • couchbase.xxx : Couchbase 관련 정보(uri, name, password)
    • infinispan.client.hotrod.xxx : Infinispan Hotrod Client 설정(기본 값으로 사용 권고)
    • infinispan.client.hotrod.server_list : Infinispan Hotrod Server 목록
    • maxActive, maxTotal, maxIdle, testOnBorrow : Infinispan Connection Pool 관련 설정(기본 값으로 사용 권고)
  4. Inifinispan Embedded / Standalone

    • WAS Embedded 형태로 구동을 원할 경우 dolly.properties 파일에 dolly.use.infinispan.embedded 값을 "true"로 설정하고, JMX 활성화를 위해 다음 System Property를 추가한다.

      • -Dcom.sun.management.jmxremote
      • -Dcom.sun.management.jmxremote.port=9999
      • -Dcom.sun.management.jmxremote.ssl=false
      • -Dcom.sun.management.jmxremote.authenticate=false
    • Standalone 형태로 구동을 원할 경우 다음과 같은 명령으로 실행 시킬 수 있다.

      • java -Ddolly.properties=/opt/dolly-agent/dolly.properties -jar core-1.1.0.jar 9999
      • 9999는 JMX 포트 번호로써 주어지지 않을 경우 9999를 기본 값으로 사용한다.
      • "nohup java -Ddolly.properties=/opt/dolly-agent/dolly.properties -jar core-1.1.0.jar 9999 > /dev/null 2>&1 &" 로 실행하여 Backgroud로 실행할 수 있다.
  5. Playce-Dolly 실행을 위한 WAS 구동 옵션 추가

    • Playce-Dolly 실행을 위해서 dolly.properties에 해당하는 System Property 및 javaagent 옵션이 필요하다.

      • -Ddolly.properties=/opt/dolly-agent/dolly.properties
      • -javaagent:/opt/dolly-agent/lib/core-1.1.0.jar
    • JBoss EAP 6 버전에서는 jboss.modules.system.pkgs 옵션에 com.athena.dolly 추가

      • -Djboss.modules.system.pkgs=org.jboss.byteman,com.athena.dolly
    • Weblogic 11 버전에서는 commons-pool 라이브러리의 충돌로 boot classpath를 지정한다.

      • -Xbootclasspath/p:/opt/dolly-agent/lib/commons-pool-1.6.jar
  6. Infinispan file-store 활성화(Embedded 및 Standalone 동작 시 제외)

    • Infinispan 서버에 Eviction과 Expiration 관련 옵션이 주어지지 않을 경우 데이터가 무한 적재되면서 OutOfMemory가 발생할 가능성이 있기 때문에 다음과 같이 캐시에 eviction 설정을 추가하고 evict 된 데이터를 파일로 저장할 수 있도록 file-store 설정을 추가한다.
 <distributed-cache name="default" mode="SYNC" segments="20" owners="2" remote-timeout="30000" start="EAGER">
    <locking isolation="READ_COMMITTED" acquire-timeout="30000" concurrency-level="1000" striping="false"/>
    <transaction mode="NONE"/>
    <eviction strategy="LRU" max-entries="8192"/>
    <!-- expiration은 dolly.properties 파일의 dolly.session.timeout 값으로 대체하여 설정된다.(lifespan은 -1, max-idle은 ${dolly.session.timeout}) --> 
    <file-store passivation="true" path="dolly" purge="false" preload="true" shared="true" />
</distributed-cache>
  • file-store에 포함될 수 있는 Attributes는 다음과 같다.
    • max-entries : Sets the maximum number of in-memory mappings between keys and their position in the store. Normally this is unlimited, but to avoid excess memory usage, an upper bound can be configured. If this limit is exceeded, entries are removed permanently using the LRU algorithm both from the in-memory index and the underlying file based cache store. Warning: setting this value may cause data loss.
    • relative-to : The base directory in which to store the cache state.
    • path : The path within "relative-to" in which to store the cache state. If undefined, the path defaults to the cache container name.
    • write-behind : Configures a cache store as write-behind instead of write-through.
    • property : A cache store property with name and value.
    • name : Uniquely identifies this store.
    • shared : This setting should be set to true when multiple cache instances share the same cache store (e.g., multiple nodes in a cluster using a JDBC-based CacheStore pointing to the same, shared database.) Setting this to true avoids multiple cache instances writing the same modification multiple times. If enabled, only the node where the modification originated will write to the cache store. If disabled, each individual cache reacts to a potential remote update by storing the data to the cache store.
    • preload : If true, when the cache starts, data stored in the cache store will be pre-loaded into memory. This is particularly useful when data in the cache store will be needed immediately after startup and you want to avoid cache operations being delayed as a result of loading this data lazily. Can be used to provide a 'warm-cache' on startup, however there is a performance penalty as startup time is affected by this process.
    • passivation : If true, data is only written to the cache store when it is evicted from memory, a phenomenon known as 'passivation'. Next time the data is requested, it will be 'activated' which means that data will be brought back to memory and removed from the persistent store. If false, the cache store contains a copy of the contents in memory, so writes to cache result in cache store writes. This essentially gives you a 'write-through' configuration.
    • fetch-state : If true, fetch persistent state when joining a cluster. If multiple cache stores are chained, only one of them can have this property enabled.
    • purge : If true, purges this cache store when it starts up.
    • singleton : If true, the singleton store cache store is enabled. SingletonStore is a delegating cache store used for situations when only one instance in a cluster should interact with the underlying store.
    • read-only : If true, the cache store will only be used to load entries. Any modifications made to the caches will not be applied to the store.

+:+:+:+: Appendix +:+:+:+:

A. SSO 처리를 위한 jsp 페이지 추가 / 수정

  1. 웹사이트 웰컴 페이지를 index.jsp, 로그인 처리 후 리턴 페이지를 login_result.jsp 라고 했을 때, login_result.jsp 에서 SSO 대상 각각의 도메인으로 초기 1회 요청을 수행해야 한다.
    • 요청 시 현재 생성된 JSESSIONID를 파라메타로 넘겨야 하며, 요청 방법은 iframe, Ajax 중 선택하여 호출한다.
  • iframe 사용
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
	<head></head>
	<body>
		<iframe src="http://www.domain1.com/index.jsp?ATHENA_DOLLY_SESSION_ID=<%= request.getSession().getId() %>" style="visibility:hidden;display:none"></iframe>
		<iframe src="http://www.domain2.com/index.jsp?ATHENA_DOLLY_SESSION_ID=<%= request.getSession().getId() %>" style="visibility:hidden;display:none"></iframe>
		<iframe src="http://www.domain3.com/index.jsp?ATHENA_DOLLY_SESSION_ID=<%= request.getSession().getId() %>" style="visibility:hidden;display:none"></iframe>
		<iframe src="http://www.domain4.com/index.jsp?ATHENA_DOLLY_SESSION_ID=<%= request.getSession().getId() %>" style="visibility:hidden;display:none"></iframe>
	</body>
</html>
  • Ajax 사용
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
	<head>
		<script type="text/javascript" src="http://code.jquery.com/jquery-1.8.0.min.js"></script>
	    <script>
			$(document).ready(function() {
				var sessionId = "<%= request.getSession().getId() %>";
	
				var urls = ["http://www.domain1.com/index.jsp?ATHENA_DOLLY_SESSION_ID=", 
							"http://www.domain2.com/index.jsp?ATHENA_DOLLY_SESSION_ID=", 
							"http://www.domain3.com/index.jsp?ATHENA_DOLLY_SESSION_ID=", 
							"http://www.domain4.com/index.jsp?ATHENA_DOLLY_SESSION_ID="];
				
				for (var i = 0; i < urls.length; i++) {
					$.ajax({
					      type: 'GET',
					      dataType: 'jsonp',
					      url: urls[i] + sessionId
					 });
				}
			});
		</script>
	</head>
	<body></body>
</html>

B. SSO 사용 시 Internet Explorer 설정 : IE는 기본적으로 개인정보취급방침(P3P)이 없는 타 도메인에 대한 쿠키를 허용하지 않는다. 따라서 브라우저 설정에서 SSO 대상 도메인에 대한 쿠키를 허용하도록 다음과 같이 설정한다.

  1. 도구 - 인터넷 옵션을 선택한다.

  2. 개인정보 탭을 선택한다.

  3. 설정 필드의 사이트 버튼을 클릭한다. ScreenShot

  4. SSO 대상 각각의 도메인을 입력하고 허용 버튼을 클릭한다. ScreenShot

    • 주의 : 포트 번호는 입력하지 않는다.
  5. 확인 버튼을 클릭한다.

C. SSO 사용 시 Safari 설정 : IE와 마찬가지로 타 도메인에 대한 쿠키를 허용하지 않으며, 다음과 같이 설정한다.

  1. Safari - 환경설정을 선택한다.
  2. 개인 정보 탭을 선택한다.
  3. 쿠키 및 웹사이트 데이터 차단 항목을 "안함"으로 선택한다. ScreenShot