F5硬件主要负责负载均衡,分发请求; EhCache主要负责缓存;Terracotta是一个集群式缓存管理类工具管理EhCache和session;
准备工作
两台linux服务器(安装配置好tomcat7和jdk1.7)
host1 : 192.168.1.21;
host2 : 192.168.1.22;安装terracotta
在多用户 . 高并发 . 高吞吐量的web应用中,用户经常要配置多个web应用服务器用以处理大量的并发请求. 如何实现多个web服务器的session高速共享, 复制是关键. 而terracotta就可以实现HttpSession共享,以及EhCache分布式缓存等其他功能, 同时TC Server本身也可以配置成集群的形式,宕机的机器(当前状态为active)的TC Server里的缓存,session等信息可以自动而无缝地转移到集群里的及其他TC Server上去, 提高了缓存数据的容灾性
terracotta版本为terracotta-3.7.7.tar.gz,下载地址,需要翻墙:http://terracotta.org/downloads/open-source/catalog
启动,start-tc-server.bat(sh) -f (读取配置文件的配置来启动) tc-config.xml
关闭,stop-tc-server.bat(sh) -n (以具体服务名称来关闭) name
启动terracotta-developer-console, bin目录下 dev-console.bat,linux下貌似不行,建议windows下做监控管理,可视化,方便查看;
3 terracotta 配置文件讲解
terracotta的核心配置文件,tc-config.xml,放在bin目录下,具体配置如下:
<?xml version="1.0" encoding="UTF-8" ?>
<tc:tc-config xmlns:tc="http://www.terracotta.org/config"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.terracotta.org/schema/terracotta-6.xsd">
<tc-properties>
<property name="l2.nha.dirtydb.autoDelete" value="true"/>
<property name="l1.cachemanager.enabled" value="true"/>
<property name="logging.maxLogFileSize" value="1024"/>
</tc-properties>
<system>
<configuration-model>development</configuration-model>
</system>
<servers>
<!--server1, 别名叫cache -->
<server host="172.16.97.29" name="cache">
<data>server-data</data>
<logs>server-logs</logs>
<index>server-index</index>
<statistics>server-statistics</statistics>
<dso-port bind="0.0.0.0">9510</dso-port>
<jmx-port bind="0.0.0.0">9520</jmx-port>
<l2-group-port bind="0.0.0.0">9530</l2-group-port>
<!--<authentication/>-->
<dso>
<client-reconnect-window>10</client-reconnect-window>
<persistence>
<mode>temporary-swap-only</mode>
</persistence>
<garbage-collection>
<enabled>true</enabled>
<verbose>false</verbose>
<interval>3600</interval>
</garbage-collection>
</dso>
</server>
<!--server2, 别名叫cache1 -->
<server host="172.16.97.30" name="cache1">
<data>server-data</data>
<logs>server-logs</logs>
<index>server-index</index>
<statistics>server-statistics</statistics>
<dso-port bind="0.0.0.0">9510</dso-port>
<jmx-port bind="0.0.0.0">9520</jmx-port>
<l2-group-port bind="0.0.0.0">9530</l2-group-port>
<!--<authentication/>-->
<dso>
<client-reconnect-window>10</client-reconnect-window>
<persistence>
<mode>temporary-swap-only</mode>
</persistence>
<garbage-collection>
<enabled>true</enabled>
<verbose>false</verbose>
<interval>3600</interval>
</garbage-collection>
</dso>
</server>
<!--可以不写这段,但是如果写了,里面cache和cache1都要写对了-->
<mirror-groups>
<mirror-group group-name="group1">
<members>
<member>cache</member>
<member>cache1</member>
</members>
<ha>
<mode>networked-active-passive</mode>
<networked-active-passive>
<election-time>5</election-time>
</networked-active-passive>
</ha>
</mirror-group>
</mirror-groups>
<!--自动更新检查,关闭 -->
<update-check>
<enabled>false</enabled>
<period-days>10</period-days>
</update-check>
</servers>
<clients>
<logs>logs-%i</logs>
</clients>
</tc:tc-config>
4 web项目引入EhCache插件配置
所需jar包(下面是通过maven方式获取,当然你下载的terracotta包里面EhCache文件lib里都有的,直接用就是,而且jar包版本兼容性都是测试通过的)
<!--EhCache核心包-->
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache-core</artifactId>
<version>2.6.8</version>
</dependency>
<!--EhCache与Terracotta结合使用-->
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache-terracotta</artifactId>
<version>2.1.1</version>
</dependency>
<!--EhCache依赖slf4j-->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.6.1</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.6.1</version>
</dependency>
EhCache.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="ehcache.xsd">
<!--将内存放入缓存中-->
<diskStore path="java.io.tmpdir" />
<cacheManagerEventListenerFactory class="" properties=""/>
<!--terracotta服务器配置,默认端口为9510,多个服务器用,分隔 -->
<terracottaConfig url="172.16.97.29:9510"/>
<!-- 默认缓存 -->
<defaultCache
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
overflowToDisk="true"
diskSpoolBufferSizeMB="30"
diskPersistent="false"
diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LRU">
</defaultCache>
<!--正式的缓存配置-->
<cache name="cache_sacm"
maxElementsInMemory="100000"
eternal="false"
memoryStoreEvictionPolicy="LRU"
timeToIdleSeconds="100000"
timeToLiveSeconds="100000"
overflowToDisk="false"
maxElementsOnDisk="0">
<terracotta clustered="true"/> <!-- 开启集群 -->
</cache>
</ehcache>
缓存使用方法:
package com.sac.core;
import net.sf.ehcache.Cache;
import net.sf.ehcache.CacheException;
import net.sf.ehcache.CacheManager;
import net.sf.ehcache.Element;
import com.sac.common.Sac;
public class EhCacheInterceptor {
static CacheManager manager=null;
static String configfile="ehcache.xml";
static String configfiletest="ehcachetest.xml";
//单点登录
public static final String single_sign_on = "cache_sacm";
//功能权限 以及科目权限
public static final String authority_recruitment_sacm ="Authority_Function_Suject";
/**
* 加密解密缓存区
*/
public static final String cache_encrypt="cache_encrypt";
static{
try {
Boolean bool =Sac.getISOpenEhcacheServer();
if(bool){
manager = CacheManager.create(EhCacheInterceptor.class.getClassLoader().getResourceAsStream(configfile));
}else{
manager = CacheManager.create(EhCacheInterceptor.class.getClassLoader().getResourceAsStream(configfiletest));
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 将数据放入缓存中
* @param cachename 缓存的名字
* @param key 缓存的key
* @param value 缓存的value
*/
public static void put(String cachename,String key,Object value){
Cache cache = manager.getCache(cachename);
if (cache != null) {
cache.put(new Element(key, value));
}
}
/**
* 根据缓存名称以及key 获取缓存数据
* @param cachename
* @param key
* @return
*/
public static Object get(String cachename,String key){
try {
Cache cache = manager.getCache(cachename);
if (cache != null) {
Element e=cache.get(key);
if(e==null)return null;
return e.getObjectValue();
}
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (CacheException e) {
e.printStackTrace();
}
return null;
}
/**
* 根据缓存名称清空缓存
* @param cachename
*/
public static void clearCache(String cachename){
try {
manager.getCache(cachename).removeAll();
} catch (IllegalStateException e) {
e.printStackTrace();
}
}
/**
* 删除缓存为cachename key的数据缓存
* @param cachename
* @param key
*/
public static void remove(String cachename,String key){
manager.getCache(cachename).remove(key);
}
}
5 tomcat结合terracotta实现session共享
所需jar包
拷贝 TerracottaHome/sessions/terracotta−session−1.1.2.jar和 {Terracotta_Home}/common/terracotta-toolkit-1.3-runtime-3.2.0.jar至tomcat安装目录的lib目录。
修改conf/context.xml文件
<!--在<WatchedResource>WEB-INF/web.xml</WatchedResource>之后添加-->
<Valve className="org.terracotta.session.TerracottaTomcat70xSessionValve" tcConfigUrl="172.16.97.29:9510,172.16.97.30:9510"/>
<!--多个terracotta服务,用逗号分隔,如上所示-->
<Valve changeSessionIdOnAuthentication="false" className="org.apache.catalina.authenticator.BasicAuthenticator"/>