记一次,ehcache缓存到磁盘,再恢复的过程

问题就是:缓存到硬盘,关闭服务器后再重启,无法获得之前缓存数据 

 

环境:

 

 

ehcache版本:

                
		    net.sf.ehcache
		    ehcache-core
		    2.5.2
		

 

 

 

ehcache.xml:

 

 




     
	
    
	

    
    
    
                 




        




    
    
    
    
                 
        





    
    
    
    
                 
        




    

   

 applicationContext-cache.xml:

 

 




	 
	
    
    
        
    
    
    
        
    



 CacheUtils:

 

 

package jiangdu.fire.util.wj;

import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cache.ehcache.EhCacheCacheManager;
import org.springframework.util.CollectionUtils;

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

/**
 * Cache工具类
 * @author wj
 * @date 2016-12-31
 */

public class CacheUtils {
	
	private static Logger logger = LoggerFactory.getLogger(CacheUtils.class);
	private static EhCacheCacheManager cacheManager = SpringContextHolder.getBean("ehcacheManager");
	
	
	 public static Object get(String cacheName, Object key) {  
	        Cache cache = getCache(cacheName);  
	        if (cache != null) {  
	        	logger.debug("------缓存["+cacheName+"] size:"+cache.getSize());
//	        	 System.out.println("------缓存["+cacheName+"] size:"+cache.getSize());  
	        	 
	        	 List keys = cache.getKeys();
	        	 if(!CollectionUtils.isEmpty(keys)){
	        		 for( String key1 : keys){
	        			 logger.debug("------缓存["+cacheName+"] key:"+key1+",value:"+cache.get(key1).getObjectValue());
//		        		 System.out.println("------缓存["+cacheName+"] key:"+key1+",value:"+cache.get(key1).getObjectValue());  
		        		
		        	}
	        	 }
	        	
	            Element element = cache.get(key);  
	            if (element != null) {  
	                return element.getObjectValue();  
	            }  
	        }  
	        return null;  
	    }  
	  
	    public static void put(String cacheName, Object key, Object value) {  
	        Cache cache = getCache(cacheName);  
	        if (cache != null) {  
	            cache.put(new Element(key, value));  
	        }  
	    }  
	  
	    public static boolean remove(String cacheName, Object key) {  
	        Cache cache = getCache(cacheName);  
	        if (cache != null) {  
	            return cache.remove(key);  
	        }  
	        return false;  
	    }  
	    public static void  flush(String cacheName) {  
	    	Cache cache = getCache(cacheName);  
	    	if (cache != null) {  
	    		 cache.flush();    
	    	}  
	    }  
	    
	    
	  
	    public static void main(String[] args) {  
	        String key = "key";  
	        String value = "hello";  
	        CacheUtils.put("mytest", key, value);  
	        System.out.println(CacheUtils.get("mytest", key));  
	    }  
	  
	/**
	 * 获得一个Cache,没有则显示日志。
	 * @param cacheName
	 * @return
	 */
	private static Cache getCache(String cacheName){
		Cache cache = cacheManager.getCacheManager().getCache(cacheName);
		if (cache == null){
			throw new RuntimeException("当前系统中没有定义“"+cacheName+"”这个缓存。");
		}
		return cache;
	}

}

 写入缓存代码:

 

 

//TODO 可以比较一下缓存里的日期和这里的最大日期
//将最大日期缓存磁盘(用于防止server关闭)。如果没有关闭,最大日期值 依然在外面静态变量里
CacheUtils.put(cacheName, cacheKeyName,maxBjsj);
//看看有没有持久化成功
org.springframework.util.Assert.isTrue(comparDate(((AtomicReference)CacheUtils.get(cacheName, cacheKeyName)).get(), maxBjsj.get())==0   ,"缓存日期和刚才日应该相等");
					
CacheUtils.flush(cacheName);

 读缓存代码:

 

 

static{
		if(CacheUtils.get(Contants.jq_maxDateCache, Contants.jq_maxDate_key) == null){
			maxBjsj = new  AtomicReference();
		}else{
			maxBjsj = (AtomicReference)CacheUtils.get(Contants.jq_maxDateCache, Contants.jq_maxDate_key);
		}
	}

 这时候,如果server关闭再开启,会读不到数据。

 

解决:

 

 

1、we.xml 加入

  net.sf.ehcache.constructs.web.ShutdownListener 

 让服务器关闭时候,调ehcache的shutdown方法。

 

2、spring 启动的时候

System.setProperty(net.sf.ehcache.CacheManager.ENABLE_SHUTDOWN_HOOK_PROPERTY,"true");

 

 

public class SpringInit implements InitializingBean, ServletContextAware{
	private static Logger logger = LoggerFactory.getLogger(SpringInit.class);
	
	@Override
	public void setServletContext(ServletContext servletContext) {
		
		logger.debug("-----init-----");
		System.setProperty(net.sf.ehcache.CacheManager.ENABLE_SHUTDOWN_HOOK_PROPERTY,"true");

		
	}

	@Override
	public void afterPropertiesSet() throws Exception {
		// TODO Auto-generated method stub
		
	}

}

 再把该BEAN配置到applicationContext.xml里面

   
	   

 。如果还不行可以改源码,修改DiskStorageFactory.DiskStorageFactory(..)方法,注释掉最后的 else if,让其不删除.index文件。

 

 

我这样就可以了。然后,server运行时候,.data文件是0kb的,server关闭后,.data文件就有内容了。。。不明所以
记一次,ehcache缓存到磁盘,再恢复的过程_第1张图片
 
记一次,ehcache缓存到磁盘,再恢复的过程_第2张图片
 可以参考:http://blog.csdn.net/kingofworld/article/details/44751029

 

 

 ----

但是运行一段时间后,在put缓存的时候,会报EOFException,但是我对象都序列化了啊。

 

你可能感兴趣的:(缓存)