読者です 読者をやめる 読者になる 読者になる

ITお絵かき修行

3歩歩いても忘れないために

EhcacheとTerracottaでキャッシュレプリケーション(3)資産作成(SV側・CL側資産)

APサーバのTomcat上にのせるSV側資産(サーブレット)およびCL側の資産を作る。

【概要】
APサーバ1号機ではリクエスト内のパラメータ値を使ったキャッシュをつくり、APサーバ2号機ではキャッシュを取得する。1号機で設定したキャッシュ値が2号機で取得できることで、異なるJVM上でキャッシュレプリケーションできていることを確認する。

【概要図(おさらい)】
f:id:hhhhhskw:20140508222521p:plain



【SV側資産の仕様:APサーバ1号機】
1.doPostにてパラメータ受け取り・キャッシュ生成を行う。(※doGetは動作確認に使う。)
2.HTTPヘッダ"X-Cache-Replication"に対応する値をキャッシュ内部のキャッシュデータの値に使用する。
→キャッシュ周りの設定は下図の通り。
f:id:hhhhhskw:20140509002548p:plain

package ap;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.sf.ehcache.Cache;
import net.sf.ehcache.CacheManager;
import net.sf.ehcache.Element;

@WebServlet(urlPatterns={"/terracotta/1.0/cacheReplication/"})
public class TerracottaServletAp01 extends HttpServlet{

	private static final long serialVersionUID = 1L;

	public void doPost(HttpServletRequest request,HttpServletResponse response) {

		// リクエストで指定させようとしたけどやめた
//		String countStr = request.getHeader("X-Cache-Replication-Count");
		String countStr = "50";

		System.out.println("AP1号機put開始 put回数:" + countStr);

		try{
			for(int i=0 ; i < Integer.parseInt(countStr) ;i++){
				String elementValue = request.getHeader("X-Cache-Replication");
				if(elementValue != null){
					// リクエストより取得した文字列をキャッシュデータに設定する
					putCache(elementValue ,i);
					try {
						// 2秒まつ
						Thread.sleep(2000);
					} catch (InterruptedException e) {
						e.printStackTrace(System.out);
					}
				}
			}
		}catch(Throwable e){
			e.printStackTrace(System.out);
		}
	}

	private void putCache(String elementValue, int i) throws Throwable{
		Cache cache = CacheManager.getInstance().getCache("terracottaCacheAP01");
		StringBuilder sb = new StringBuilder();
		sb.append(elementValue);
		sb.append(i);
                // ElementクラスはEhcacheが用意するキャッシュデータ格納用クラス
		cache.put(new Element("key", sb.toString()));
		System.out.println("[put]値:"+ sb.toString());
		System.out.println(System.nanoTime());
	}

	// 確認用
	public void doGet(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException{
		System.out.println("doGet");
	}
}


【SV側資産の仕様:APサーバ2号機】
1.doPostを契機として、キャッシュデータの取得を始める。(※doGetは動作確認に使う。)
→AP1号機と同一Cache名、同一キャッシュデータ名の値を取得することで、
 AP1号機にて設定された値が取得できることを確認する。

package ap;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.sf.ehcache.Cache;
import net.sf.ehcache.CacheManager;
import net.sf.ehcache.Element;

@WebServlet(urlPatterns={"/terracotta/1.0/cacheReplication/"})
public class TerracottaServletAp02 extends HttpServlet{

	private static final long serialVersionUID = 1L;

	public void doPost(HttpServletRequest request,HttpServletResponse response){

		try {
			long startTime = System.nanoTime();
			long endTime = 0;
			long elapsedTime = endTime - startTime;

			// 1分間ループ
			while(elapsedTime < 60000){
				Cache cache = CacheManager.getInstance().getCache("terracottaCacheAP01");
				Element value = cache.get("key");
				System.out.println("[get]値:"+ value.toString());
				endTime = System.nanoTime();
				System.out.println(endTime);
				// 1秒まつ
				Thread.sleep(1000);
			}
		}catch(Throwable e){
			e.printStackTrace(System.out);
		}
	}

	// 確認用
	public void doGet(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException{
		System.out.println("doGet");
	}
}


【CL側資産の仕様】
1.APサーバ1号機に対してdoPostした後、APサーバ2号機へdoPostする。

package main;

import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.ProtocolException;
import java.net.URL;

public class Ap01Cliant {

    private static final String AP01_SERVER_NAME = "http://(APサーバ1号機のホスト名もしくはIPアドレス)/terracotta/cacheReplication/";
    private static final String AP02_SERVER_NAME = "http://(APサーバ2号機のホスト名もしくはIPアドレス)/terracotta/cacheReplication/";

	public static void main(String[] args) {

		doPostForAP(AP01_SERVER_NAME);

		doPostForAP(AP02_SERVER_NAME);

	}

	private static void doPostForAP(String address) {

		try {
			// 準備
			URL url = new URL(address);
			HttpURLConnection urlconn = (HttpURLConnection)url.openConnection();
			urlconn.setRequestMethod("POST");
			urlconn.setInstanceFollowRedirects(false);
			urlconn.setRequestProperty("Accept-Language", "ja;q=0.7,en;q=0.3");
                        if(AP01_SERVER_NAME.equals(address)){
			        urlconn.setRequestProperty("X-Cache-Replication", "AP01Cliant to AP01");
                        }

			urlconn.connect();
			urlconn.getHeaderFields();
			urlconn.disconnect();
		} catch (MalformedURLException e) {
			e.printStackTrace(System.out);
		} catch (ProtocolException e) {
			e.printStackTrace(System.out);
		} catch (IOException e) {
			e.printStackTrace(System.out);
		}
	}
}


※各数値に絶対的な根拠はない。
※キャッシュ設定値などの情報は、AP1・2号機ともに「System.out.println()」で標準出力に出力している。なのでAP1号機・AP2号機の実行結果はCatalina.outを「tail -f」等して確かめることとする。
JSPで画面に出力しようと思ったが、キャッシュレプリケーション以外の通信を行いたくなかったので、サーバへの出力はAPサーバ内のサーバのログ(今回はCatalina.out)で確認する。


資産の構成は以下の通り。
(※直接編集しない・配置しないファイルは記述していない。)

【APサーバ1号機にのせる資産】
Tomcatプロジェクト。コンテキストパスは「/AP01」

├─AP01
│  │  
│  ├─bin
│  ├─lib
│  │      ehcache-core-2.6.8.jar
│  │      ehcache-terracotta-2.6.8.jar
│  │      slf4j-api-1.6.1.jar
│  │      slf4j-jdk14-1.6.1.jar
│  │      terracotta-toolkit-1.6-runtime-5.7.0.jar
│  │      
│  ├─src
│  ├─WEB-INF
│  │  │  
│  │  ├─classes
│  │  │  └─ap
│  │  │          TerracottaServletAp01.class
│  │  │          
│  │  ├─lib
│  │  │      config.jar (※定義体を格納するjarファイル)
│  │  │      ehcache-core-2.6.8.jar
│  │  │      ehcache-terracotta-2.6.8.jar
│  │  │      slf4j-api-1.6.1.jar
│  │  │      slf4j-jdk14-1.6.1.jar
│  │  │      terracotta-toolkit-1.6-runtime-5.7.0.jar
│  │  │      
│  │  └─src
│  │      └─ap
│  │              TerracottaServletAp01.java
│  │              
│  └─work


【APサーバ2号機にのせる資産】
Tomcatプロジェクト。コンテキストパスは「/AP02」

├─AP02
│  ├─bin
│  ├─lib
│  │      ehcache-core-2.6.8.jar
│  │      ehcache-terracotta-2.6.8.jar
│  │      slf4j-api-1.6.1.jar
│  │      slf4j-jdk14-1.6.1.jar
│  │      terracotta-toolkit-1.6-runtime-5.7.0.jar
│  │      
│  ├─src
│  ├─WEB-INF
│  │  │  
│  │  ├─classes
│  │  │  └─ap
│  │  │          TerracottaServletAp02.class
│  │  │          
│  │  ├─lib
│  │  │      config.jar (※定義体を格納するjarファイル)
│  │  │      ehcache-core-2.6.8.jar
│  │  │      ehcache-terracotta-2.6.8.jar
│  │  │      slf4j-api-1.6.1.jar
│  │  │      slf4j-jdk14-1.6.1.jar
│  │  │      terracotta-toolkit-1.6-runtime-5.7.0.jar
│  │  │      
│  │  └─src
│  │      └─ap
│  │              TerracottaServletAp02.java
│  │              
│  └─work

【CL側資産】

├─CL
│  │      
│  ├─bin
│  │  └─main
│  │          Ap01Cliant.class
│  │
│  ├─lib
│  │      
│  └─src
│     └─main
│             Ap01Cliant.java          

【定義体を格納するだけの資産】

├─CONFIG
│  │      
│  ├─bin
│  ├─src
│  └─xml
│          ehcache.xml


次はApacheTomcat等の定義体を作り、資産と定義体をサーバにのせて動作確認を行う。