All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.jeesuite.cache.local.Level1CacheSupport Maven / Gradle / Ivy

There is a newer version: 1.4.0
Show newest version
package com.jeesuite.cache.local;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import org.apache.commons.lang3.Validate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.util.StringUtils;

import com.jeesuite.spring.InstanceFactory;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.JedisPubSub;

/**
 * 本地缓存同步处理器
 * @description 
* @author vakin * @date 2016年6月21日 */ public class Level1CacheSupport implements InitializingBean, DisposableBean{ private static final Logger logger = LoggerFactory.getLogger(Level1CacheSupport.class); private String channelName = "clearLevel1_"; private String bcastServer; private boolean distributedMode = true; //是否启用分布式模式 private String password; private List cacheNames; // private Jedis subJedisClient; private JedisPool pupJedisPool; private ScheduledExecutorService redisCheckTimer; private Level1CacheProvider cacheProvider; private LocalCacheSyncListener listener; private static Level1CacheSupport instance; public static Level1CacheSupport getInstance() { if(instance == null){ synchronized (Level1CacheSupport.class) { if(instance == null)instance = InstanceFactory.getInstance(Level1CacheSupport.class); if(instance == null)instance = new Level1CacheSupport(); } } return instance; } public boolean publishSyncEvent(String key){ if(cacheNames == null)return true; String cacheName = key.split("\\.")[0]; if(!cacheNames.contains(cacheName))return true; //删除本地 cacheProvider.remove(cacheName, key); logger.debug("remove local LEVEL1 cache: cacheName:[{}], key:[{}]",cacheName,key); if(!distributedMode)return true; boolean publish = publish(channelName, new ClearCommand(cacheName, key).serialize()); if(publish){ logger.debug("broadcast command for key:[{}] by channelName:[{}]",key,channelName); } return publish; } private boolean publish(String channel,String message){ Jedis jedis = null; try { jedis = pupJedisPool.getResource(); return jedis.publish(channel, message) > 0; } finally { if(jedis != null)jedis.close(); } } public boolean set(String key, Object value) { if(cacheNames == null)return true; String cacheName = key.split("\\.")[0]; if(!cacheNames.contains(cacheName))return true; boolean result = cacheProvider.set(cacheName, key, value); if(logger.isDebugEnabled())logger.debug("set LEVEL1 cache:{}",key); return result; } public T get(String key) { if(cacheNames == null)return null; String cacheName = key.split("\\.")[0]; if(!cacheNames.contains(cacheName))return null; T object = cacheProvider.get(cacheName, key); if(object != null)logger.debug("get cache:{} from LEVEL1",key); return object; } public void remove(String key) { if(cacheNames == null)return; String cacheName = key.split("\\.")[0]; if(!cacheNames.contains(cacheName))return; cacheProvider.remove(cacheName, key); logger.debug("remove LEVEL1 cache,cacheName:{},key:{}",cacheName,key); } @Override public void afterPropertiesSet() throws Exception { if(cacheNames == null)return; if(cacheProvider == null){ cacheProvider = new GuavaLevel1CacheProvider(); } // cacheProvider.start(); // if(!distributedMode)return; Validate.notBlank(bcastServer); String[] serverInfos = StringUtils.tokenizeToStringArray(bcastServer, ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS)[0].split(":"); final String host =serverInfos[0]; final int port = Integer.parseInt(serverInfos[1]); listener = new LocalCacheSyncListener(); redisCheckTimer = Executors.newScheduledThreadPool(1); redisCheckTimer.scheduleWithFixedDelay(new Runnable() { @Override public void run() { if(subJedisClient == null){ try { subJedisClient = new Jedis(host, port); if(password != null)subJedisClient.auth(password); if("PONG".equals(subJedisClient.ping())){ logger.info("subscribe localCache sync channel....."); subJedisClient.subscribe(listener, new String[]{channelName}); } } catch (Exception e) { try {listener.unsubscribe();} catch (Exception ex) {} try { subJedisClient.close(); } catch (Exception e2) {}finally { subJedisClient = null; } } } } }, 0, 30, TimeUnit.SECONDS); // JedisPoolConfig poolConfig = new JedisPoolConfig(); poolConfig.setMaxIdle(1); poolConfig.setMinEvictableIdleTimeMillis(60 * 1000); poolConfig.setMaxTotal(10); poolConfig.setMaxWaitMillis(30 * 1000); pupJedisPool = new JedisPool(poolConfig, host, port, 3000, password); } @Override public void destroy() throws Exception { if(cacheProvider != null)cacheProvider.close(); if(redisCheckTimer != null)redisCheckTimer.shutdown(); try {listener.unsubscribe();} catch (Exception e) {} if(subJedisClient != null){ subJedisClient.close(); } if(pupJedisPool != null){ pupJedisPool.close(); } } public void setBcastServer(String servers) { this.bcastServer = servers; } public void setPassword(String password) { this.password = password; } public void setCacheProvider(Level1CacheProvider cacheProvider) { this.cacheProvider = cacheProvider; } public void setDistributedMode(boolean distributedMode) { this.distributedMode = distributedMode; } public void setBcastScope(String bcastScope) { this.channelName = "clearLevel1_" + bcastScope; } public void setCacheNames(String cacheNames) { if(org.apache.commons.lang3.StringUtils.isBlank(cacheNames)){ return; } String[] tmpcacheNames= StringUtils.tokenizeToStringArray(cacheNames, ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS); this.cacheNames = new ArrayList<>(Arrays.asList(tmpcacheNames)); } private class LocalCacheSyncListener extends JedisPubSub { private static final String CLEAR_ALL = "clearall"; @Override public void onMessage(String channel, String message) { super.onMessage(channel, message); if(channel.equals(channelName)){ if(CLEAR_ALL.equals(message)){ cacheProvider.clearAll(); logger.info("receive command {} and clear local cache finish!",CLEAR_ALL); }else{ try { ClearCommand command = ClearCommand.deserialize(message); if(command.isLocalCommand()){ return; } cacheProvider.remove(command.getCacheName(), command.getKey()); } catch (Exception e) {} } } } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy