Tomcat中部署多个war服务Ehcache故障

一、场景说明

场景1:同一份war被copy多份部署到同一Tomcat中运行,此时cacheManager的名称是相同的(多版本部署修改war名称:ROOT.war、v1.war、v2.war)

场景2:多个不同的war被部署到同一Tomcat中运行,多个war中cacheManager命名出现相同

说  明:

1)药师360药品说明书项目遇到的为场景1,多版本部署在同一Tomcat中

2)此处为了解决Tomcat中多个war服务Ehcache故障问题,对于RMI缓存集群共享不在此文档范围

 

二、解决过程

Tomcat服务启动时会出现异常(只有一个war服务正常):

Invocation of init method failed; nested exception is net.sf.ehcache.CacheException: Another CacheManager with same name 'drug-instruction' already exists in the same VM. 
Please provide unique names for each CacheManager in the config or do one of following:
1. Use one of the CacheManager.create() static factory methods to reuse same CacheManager with same name or create one if necessary
2. Shutdown the earlier cacheManager before creating new one with same name.

原因:Ehcache是进程内缓存,进程内缓存共享,此时将ehcache.xml中缓存配置加上:『p:shared="true" 』,如下:

<bean id="appCacheManageBean" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"
p:configLocation="classpath:spring/drug-instruction-ehcache.xml" p:shared="true" />

 

修改后重新部署、启动Tomcat此时能够正常启动,但当请求的服务使用到缓存的地方又出现故障(第一个A服务正常,其他B出现故障),如下:

java.lang.ClassCastException: com.oncloudit.drug.instruction.dto.Hospital cannot be cast to com.oncloudit.drug.instruction.dto.Hospital

分析:首先访问A服务此时将对象缓存至Ehcache缓存中,B服务请求缓存是可以拿个改对象(只是此对象属于A),但转换失败;

估计是Tomcat不同的war服务context不一样、其对应的内存区域不一样,但Ehcache是进程内缓存共享,所以可以取到值,但类型转换失败。

 

解决方式一:将缓存对象序列化、反序列化就可以使用了,或:Hospital hospital = JsonUtil.json2Object(JsonUtil.object2Json(hospital), new TypeReference<Hospital>() {});

解决方式二:A、B两个war中因cacheManager名称相同,此时可以动态创建名称不同的cache或动态生成cache-key,此处采用动态生成cache-key举例:

步骤1)A、B两个程序中定义全局变量

public static final String APP_UNIQUE_IDENTIFIER = UUID.randomUUID().toString();

步骤2)不同项目cache-key前缀不同

public static final String CACHE_KEY_HOSPITAL = ConfigConstant.APP_UNIQUE_IDENTIFIER + "_hospital";

缓存key使用此种方式,这样不同的war服务中cacheManager名称可以相同,不同war项目可以正常工作

解决方式三:不使用Ehcache(改用memcache、redis ...)或war部署至不同的Tomcat服务中

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值