TomcatでJNDI方式でJbossCacheを発表します。
10956 ワード
前言:
JbossCacheの開発マニュアルを見ましたが、JbossCacheとAppServerの統合章節はJNDI方式の集積に対して明確に説明されていません。JbossアプリServerの下で、MBean方式でJbossCacheを管理できます。もっと多い場合、Factory類を書く必要があります。API方法でJbossCacheを有効にします。
企業の応用において、特にSOA構造のシステムでは、一つのアプリケーションサーバで複数のアプリケーションを同時に実行するシーンがよく見られます。JbossCacheはグループキャッシュの実現として、一つのアプリケーションサーバ上のマルチアプリケーションに対して、一つのJBossCacheの実例を共有したいです。
1.Tomcat JNDI実現
Tomcat JNDIはみんなが接触したことがあると思います。一番よく使うのはデータベースのDataSourceです。Tomcatサーバーが起動した後、JNDIはRead Onlyモードを示しています。API方式でリソースをアップロードできません。したがって、私たちは声明を構成するJNDI JbossCacheサービスを実現する必要があります。
Cache論理関連インターフェースを宣言します。CusterCache
CusterCacheインターフェースはJbossCacheのCacheインターフェースの簡素化されたパッケージである。コードは以下の通りです
どのリソースもJNDIとしてリリースするには、javax.naming.Referenceableインターフェースを実現する必要があります。このインターフェースは一つの方法しかないです。それはjavax.naming.Referenceタイプのオブジェクトを返します。JNDIのSPI端は、このReferenceオブジェクトがJNDIリソースインスタンスを初期化し、ユーザに提供するために十分な情報を提供する必要がある。
CusterCache業務インターフェースに対するReferenceableは以下の通り実現される。
2.TomcatのサーバでJbossCacheのJNDIサービスクラスを全ローカルに発表します。
Tomcatを発表するグローバルJNDIはみんながやったことがあると信じています。ここでは読者のための考えを続けています。もう一回くどいです。
jarパッケージをリリース
グローバルJNDIの発表を行います。jarカバンをTomcatの\libディレクトリにコピーする必要があります。したがって、上記の二つの種類を一つのjarに包装します。例えば、CusterCache.jar、JbossCacheのJARバッグを持ってlibディレクトリにコピーします。JbossCache関連のカバンリストは以下の通りです。 jbosscache-core-34.2.1 commons-loging-1.11.jar jboss-common-core.jar jboss-loging-spi.jar jboss-tractionn-ap.jar(jta.jar) jcip-annotations.jar jgroups.jar また、JNDIClusterCacheでは、jbosscacheのプロファイルはjbosscache.cfg.xmlであると宣言していますので、私たちもこのプロファイルをlibディレクトリに拷問します。
Tomcat全体のリソースを設定します。
Tomcatの\confディレクトリの下で、context.xmlファイルが見つかりました。ここに以下の構成を加えます。
JNDI Cacheを使用するweb.xmlにcacheリソースに対する参照配置を追加します。
しかし、このようにしても、JNDI上のJbosscacheは各アプリケーションに分布しているCacheListenerモニターを使用できなくなります。理由はTomcatのグローバルlibのクラスリーダーはウェブアプリケーションのクラスクラスリーダーよりもクラスローディングレベルの下にいます。簡単に言うと、web-inf\libのクラスはグローバルlibのクラスを引用することができますが、グローバルlibのクラスはweb-inf\libのjarクラスを逆に適用できません。
【全文完了】
JbossCacheの開発マニュアルを見ましたが、JbossCacheとAppServerの統合章節はJNDI方式の集積に対して明確に説明されていません。JbossアプリServerの下で、MBean方式でJbossCacheを管理できます。もっと多い場合、Factory類を書く必要があります。API方法でJbossCacheを有効にします。
企業の応用において、特にSOA構造のシステムでは、一つのアプリケーションサーバで複数のアプリケーションを同時に実行するシーンがよく見られます。JbossCacheはグループキャッシュの実現として、一つのアプリケーションサーバ上のマルチアプリケーションに対して、一つのJBossCacheの実例を共有したいです。
1.Tomcat JNDI実現
Tomcat JNDIはみんなが接触したことがあると思います。一番よく使うのはデータベースのDataSourceです。Tomcatサーバーが起動した後、JNDIはRead Onlyモードを示しています。API方式でリソースをアップロードできません。したがって、私たちは声明を構成するJNDI JbossCacheサービスを実現する必要があります。
Cache論理関連インターフェースを宣言します。CusterCache
CusterCacheインターフェースはJbossCacheのCacheインターフェースの簡素化されたパッケージである。コードは以下の通りです
package org.wltea.cache;
import java.util.Map;
import java.util.Set;
import org.jboss.cache.Node;
public interface ClusterCache {
/**
* cache
*/
public void beginBatchTx();
/**
* cache
*/
public void commitBatchTx();
/**
* cache
*/
public void rollbackBatchTx();
/**
* key-value
* @param nodePath :/aaa/bbb/ccc ,
* @param key
* @param value
*/
public void cacheData(String nodePath , String key , Object value);
/**
* Map
* @param nodePath :/aaa/bbb/ccc ,
* @param dataMap Map
*/
public void cacheDataMap(String nodePath , Map<String , Object> dataMap);
/**
*
* @param nodePath :/aaa/bbb/ccc ,
* @param key
* @return Object
*/
public Object getCacheData(String nodePath , String key);
/**
*
* @param nodePath :/aaa/bbb/ccc ,
* @return Map Map
*/
public Map<String , Object> getCacheDataMap(String nodePath);
/**
*
* @param nodePath :/aaa/bbb/ccc ,
*/
public void clearData(String nodePath);
/**
*
* @param nodePath :/aaa/bbb/ccc ,
*/
public int getDataSize(String nodePath);
/**
*
* @param nodePath
* @return Set<Node<String,Object>> ,
*/
public Set<Node<String,Object>> getChildren(String nodePath);
/**
*
* @param nodePath :/aaa/bbb/ccc ,
* @param key
* @return Object
*/
public Object removeData(String nodePath , String key);
/**
*
* @param nodePath :/aaa/bbb/ccc ,
* @return boolean true: ; false:
*/
public boolean removeNode(String nodePath);
}
CusterCacheインターフェースをリリース可能なJNDI参照に実現する。どのリソースもJNDIとしてリリースするには、javax.naming.Referenceableインターフェースを実現する必要があります。このインターフェースは一つの方法しかないです。それはjavax.naming.Referenceタイプのオブジェクトを返します。JNDIのSPI端は、このReferenceオブジェクトがJNDIリソースインスタンスを初期化し、ユーザに提供するために十分な情報を提供する必要がある。
CusterCache業務インターフェースに対するReferenceableは以下の通り実現される。
/**
*
*/
package org.wltea.cache;
import java.util.Map;
import java.util.Set;
import javax.naming.NamingException;
import javax.naming.Reference;
import javax.naming.Referenceable;
import org.jboss.cache.Cache;
import org.jboss.cache.CacheFactory;
import org.jboss.cache.DefaultCacheFactory;
import org.jboss.cache.Fqn;
import org.jboss.cache.Node;
/**
* JNDI
* @author
*
*/
public class JNDIClusterCache implements Referenceable , ClusterCache{
//
private static String CONFIG_FILE_LOCATION = "jbosscache.cfg.xml";
//Jboss Cache
private static final CacheFactory<String , Object> factory = new DefaultCacheFactory<String , Object>();
//Jboss cache
private static Cache<String , Object> cache = null;
// JNDI
private String factoryClassName = "org.apache.naming.factory.BeanFactory";
public String getFactoryClassName() {
return factoryClassName;
}
public void setFactoryClassName(String factoryClassName) {
this.factoryClassName = factoryClassName;
}
public JNDIClusterCache(){
if(cache == null){
synchronized(JNDIClusterCache.class){
if(cache == null){
cache = factory.createCache(CONFIG_FILE_LOCATION);
}
}
}
}
/**
* JNDI
*/
public Reference getReference() throws NamingException {
Reference ref=new Reference(getClass().getName(),getFactoryClassName(),null);
// Reference
//ref.add(new StringRefAddr("location",location));
//ref.add(new StringRefAddr("state",state));
return ref;
}
/**
* cache
*/
public void beginBatchTx(){
cache.startBatch();
}
/**
* cache
*/
public void commitBatchTx(){
cache.endBatch(true);
}
/**
* cache
*/
public void rollbackBatchTx(){
cache.endBatch(false);
}
/**
* key-value
* @param nodePath :/aaa/bbb/ccc ,
* @param key
* @param value
*/
public void cacheData(String nodePath , String key , Object value){
Fqn<String> fqn = Fqn.fromString(nodePath);
cache.put(fqn, key, value);
}
/**
* Map
* @param nodePath :/aaa/bbb/ccc ,
* @param dataMap Map
*/
public void cacheDataMap(String nodePath , Map<String , Object> dataMap){
Fqn<String> fqn = Fqn.fromString(nodePath);
cache.put(fqn, dataMap);
}
/**
*
* @param nodePath :/aaa/bbb/ccc ,
* @param key
* @return Object
*/
public Object getCacheData(String nodePath , String key){
Fqn<String> fqn = Fqn.fromString(nodePath);
return cache.get(fqn, key);
}
/**
*
* @param nodePath :/aaa/bbb/ccc ,
* @return Map Map
*/
public Map<String , Object> getCacheDataMap(String nodePath){
Fqn<String> fqn = Fqn.fromString(nodePath);
return cache.getData(fqn);
}
/**
*
* @param nodePath :/aaa/bbb/ccc ,
*/
public void clearData(String nodePath){
Fqn<String> fqn = Fqn.fromString(nodePath);
Node<String,Object> node = cache.getNode(fqn);
node.clearData();
}
/**
*
* @param nodePath :/aaa/bbb/ccc ,
*/
public int getDataSize(String nodePath){
Fqn<String> fqn = Fqn.fromString(nodePath);
Node<String,Object> node = cache.getNode(fqn);
return node.dataSize();
}
/**
*
* @param nodePath
* @return Set<Node<String,Object>> ,
*/
public Set<Node<String,Object>> getChildren(String nodePath){
Fqn<String> fqn = Fqn.fromString(nodePath);
Node<String,Object> node = cache.getNode(fqn);
return node.getChildren();
}
/**
*
* @param nodePath :/aaa/bbb/ccc ,
* @param key
* @return Object
*/
public Object removeData(String nodePath , String key){
Fqn<String> fqn = Fqn.fromString(nodePath);
return cache.remove(fqn, key);
}
/**
*
* @param nodePath :/aaa/bbb/ccc ,
* @return boolean true: ; false:
*/
public boolean removeNode(String nodePath){
Fqn<String> fqn = Fqn.fromString(nodePath);
return cache.removeNode(fqn);
}
}
説明するには、CusterCacheの実装において、Jbosscacheに対して単一のインスタンスが採用されている。JbosscacheのAPI文書によると、Cacheの実現はThreadSafeのものである。2.TomcatのサーバでJbossCacheのJNDIサービスクラスを全ローカルに発表します。
Tomcatを発表するグローバルJNDIはみんながやったことがあると信じています。ここでは読者のための考えを続けています。もう一回くどいです。
jarパッケージをリリース
グローバルJNDIの発表を行います。jarカバンをTomcatの\libディレクトリにコピーする必要があります。したがって、上記の二つの種類を一つのjarに包装します。例えば、CusterCache.jar、JbossCacheのJARバッグを持ってlibディレクトリにコピーします。JbossCache関連のカバンリストは以下の通りです。
Tomcat全体のリソースを設定します。
Tomcatの\confディレクトリの下で、context.xmlファイルが見つかりました。ここに以下の構成を加えます。
<Resource name="ik/clustercache"
auth="Container"
type="com.wltea.cache.JNDIClusterCache"
factory="org.apache.naming.factory.BeanFactory"/>
Webアプリの設定のクライアントJNDI参照JNDI Cacheを使用するweb.xmlにcacheリソースに対する参照配置を追加します。
<resource-ref>
<description>JNDI Cluster Cache</description>
<res-ref-name>ik/clustercache</res-ref-name>
<res-type>com.wltea.cache.ClusterCache</res-type>
<res-auth>Container</res-auth>
</resource-ref>
アプリケーションでJNDI上のJbossCacheを取得します。
// Put your code here
Context initContext;
try {
initContext = new InitialContext();
Context envContext = (Context)initContext.lookup("java:/comp/env");
ClusterCache cache = (ClusterCache)envContext.lookup("ik/clustercache");
} catch (NamingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
これまでJbossCacheをTomcatのJNDIにリリースすることができました。このようにする利点は、アプリケーションサーバはJbossCacheサービスの一例だけであり、グループ化サーバCache間の同期がより効率的になり、メモリ及びCPUリソースの消費がより少なくなることである。しかし、このようにしても、JNDI上のJbosscacheは各アプリケーションに分布しているCacheListenerモニターを使用できなくなります。理由はTomcatのグローバルlibのクラスリーダーはウェブアプリケーションのクラスクラスリーダーよりもクラスローディングレベルの下にいます。簡単に言うと、web-inf\libのクラスはグローバルlibのクラスを引用することができますが、グローバルlibのクラスはweb-inf\libのjarクラスを逆に適用できません。
【全文完了】