Skip to content

Commit

Permalink
增加JedisCluster的支持
Browse files Browse the repository at this point in the history
  • Loading branch information
邱家榆 committed Nov 1, 2016
1 parent 76e7843 commit ed35069
Show file tree
Hide file tree
Showing 8 changed files with 196 additions and 22 deletions.
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>com.github.qiujiayu</groupId>
<artifactId>autoload-cache</artifactId>
<version>4.16</version>
<version>4.17</version>
<packaging>jar</packaging>
<name>AutoLoadCache</name>
<description>User AOP and annotation to do with cache.</description>
Expand Down
13 changes: 5 additions & 8 deletions src/main/java/com/jarvis/cache/admin/servlet/AdminServlet.java
Original file line number Diff line number Diff line change
Expand Up @@ -161,8 +161,7 @@ private void printHtmlHead(HttpServletResponse resp, String cacheManagerName) th
html.append("<html>").append("<head>").append("<title>Cache Admin</title>");
html.append("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />");
html.append("<style type=\"text/css\">");
html.append(
"th {text-align: center; line-height: 24px; border-top: 1px solid #555555; border-bottom: 1px solid #555555; border-right: 1px solid #555555; word-wrap: break-word; }");
html.append("th {text-align: center; line-height: 24px; border-top: 1px solid #555555; border-bottom: 1px solid #555555; border-right: 1px solid #555555; word-wrap: break-word; }");
html.append("table { border-left: 1px solid #555555; }");
html.append("td { border-right: 1px solid #555555; border-bottom: 1px solid #555555; text-align: center; line-height: 24px; word-wrap: break-word; }");
html.append("</style>");
Expand Down Expand Up @@ -223,8 +222,7 @@ private void printForm(HttpServletResponse resp, String cacheManagerName, String
html.append("</select>");
html.append("<input type=\"submit\" value=\"更改缓存\"></input>");
html.append("</form>");
html.append(
"cache key:<input type=\"text\" id=\"deleteCacheKey\"/> <input type=\"button\" onclick=\"removeCache(document.getElementById('deleteCacheKey').value)\" value=\"删除缓存\"/>");
html.append("cache key:<input type=\"text\" id=\"deleteCacheKey\"/> <input type=\"button\" onclick=\"removeCache(document.getElementById('deleteCacheKey').value)\" value=\"删除缓存\"/>");
html.append("<form id=\"updateCacheForm\" action=\"\" method=\"get\" target=\"_blank\">");
html.append("<input type=\"hidden\" id=\"act\" name=\"act\" value=\"\" />");
html.append("<input type=\"hidden\" id=\"cacheKey\" name=\"cacheKey\" value=\"\" />");
Expand Down Expand Up @@ -280,8 +278,7 @@ private void printList(HttpServletRequest req, HttpServletResponse resp, Abstrac
html.append(" <td>" + getDateFormat(tmpTO.getFirstRequestTime()) + "</td>");
html.append(" <td>" + tmpTO.getRequestTimes() + "次</td>");
html.append(" <td>" + getDateFormat(tmpTO.getLastLoadTime() + tmpTO.getCache().expire() * 1000) + "(" + tmpTO.getCache().expire() + "秒)</td>");
html.append(
" <td>" + getDateFormat(tmpTO.getLastRequestTime() + tmpTO.getCache().requestTimeout() * 1000) + "(" + tmpTO.getCache().requestTimeout() + "秒)</td>");
html.append(" <td>" + getDateFormat(tmpTO.getLastRequestTime() + tmpTO.getCache().requestTimeout() * 1000) + "(" + tmpTO.getCache().requestTimeout() + "秒)</td>");
html.append(" <td>" + getDateFormat(tmpTO.getLastLoadTime()) + "</td>");
html.append(" <td>" + tmpTO.getLoadCnt() + "次</td>");
html.append(" <td>" + tmpTO.getAverageUseTime() + "毫秒</td>");
Expand All @@ -290,8 +287,8 @@ private void printList(HttpServletRequest req, HttpServletResponse resp, Abstrac
html.append(" <td><a href=\"javascript:void()\" onclick=\"resetLastLoadTime('" + _key + "','" + _hfield + "')\">重置最后加载时间</a></td>");
html.append("<td>");
if(null != tmpTO.getArgs() && tmpTO.getArgs().length > 0) {
html.append("<a href=\"" + req.getContextPath() + req.getServletPath() + "?act=showArgs&cacheManagerName=" + cacheManagerName + "&cacheKey=" + _key
+ "&hfield=" + _hfield + "\" target=\"_blank\">show args values</a>");
html.append("<a href=\"" + req.getContextPath() + req.getServletPath() + "?act=showArgs&cacheManagerName=" + cacheManagerName + "&cacheKey=" + _key + "&hfield=" + _hfield
+ "\" target=\"_blank\">show args values</a>");
}
html.append("</td>");
html.append(" </tr>");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@
import com.jarvis.cache.to.AutoLoadTO;

/**
* 排序算法:越接近过期时间,越耗时的排在最前,即: System.currentTimeMillis() - autoLoadTO.getLastLoadTime()-autoLoadTO.getExpire()*1000 值越大,排在越前
* autoLoadTO.getAverageUseTime() 值越大,排在越前
* 排序算法:越接近过期时间,越耗时的排在最前,即: System.currentTimeMillis() - autoLoadTO.getLastLoadTime()-autoLoadTO.getExpire()*1000 值越大,排在越前 autoLoadTO.getAverageUseTime() 值越大,排在越前
* @author jiayu.qiu
*/
public class AutoLoadOldestComparator implements Comparator<AutoLoadTO> {
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/com/jarvis/cache/map/CachePointCut.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
* @author jiayu.qiu
*/
public class CachePointCut extends AbstractCacheManager {

private static final Logger logger=Logger.getLogger(CachePointCut.class);

private final ConcurrentHashMap<String, Object> cache=new ConcurrentHashMap<String, Object>();
Expand Down Expand Up @@ -117,7 +117,7 @@ public void setCache(final CacheKeyTO cacheKeyTO, final CacheWrapper<Object> res
if(tmpObj instanceof ConcurrentHashMap) {
hash=(ConcurrentHashMap<String, SoftReference<CacheWrapper<Object>>>)tmpObj;
} else {
logger.error(method.getClass().getName()+"."+method.getName()+"中key为"+cacheKey+"的缓存,已经被占用,请删除缓存再试。");
logger.error(method.getClass().getName() + "." + method.getName() + "中key为" + cacheKey + "的缓存,已经被占用,请删除缓存再试。");
return;
}
}
Expand Down
182 changes: 182 additions & 0 deletions src/main/java/com/jarvis/cache/redis/JedisClusterCacheManager.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
package com.jarvis.cache.redis;

import java.lang.reflect.Method;
import java.lang.reflect.Type;

import org.apache.log4j.Logger;

import com.jarvis.cache.AbstractCacheManager;
import com.jarvis.cache.exception.CacheCenterConnectionException;
import com.jarvis.cache.script.AbstractScriptParser;
import com.jarvis.cache.serializer.ISerializer;
import com.jarvis.cache.serializer.StringSerializer;
import com.jarvis.cache.to.AutoLoadConfig;
import com.jarvis.cache.to.CacheKeyTO;
import com.jarvis.cache.to.CacheWrapper;

import redis.clients.jedis.JedisCluster;
import redis.clients.jedis.ShardedJedis;

/**
* Redis缓存管理
* @author jiayu.qiu
*/
public class JedisClusterCacheManager extends AbstractCacheManager {

private static final Logger logger=Logger.getLogger(JedisClusterCacheManager.class);

private static final StringSerializer keySerializer=new StringSerializer();

private JedisCluster jedisCluster;

/**
* Hash的缓存时长:等于0时永久缓存;大于0时,主要是为了防止一些已经不用的缓存占用内存;hashExpire小于0时,则使用@Cache中设置的expire值(默认值为-1)。
*/
private int hashExpire=-1;

/**
* 是否通过脚本来设置 Hash的缓存时长
*/
private boolean hashExpireByScript=false;

public JedisClusterCacheManager(AutoLoadConfig config, ISerializer<Object> serializer, AbstractScriptParser scriptParser) {
super(config, serializer, scriptParser);
}

private void returnResource(ShardedJedis shardedJedis) {
shardedJedis.close();
}

@Override
public void setCache(final CacheKeyTO cacheKeyTO, final CacheWrapper<Object> result, final Method method, final Object args[]) throws CacheCenterConnectionException {
if(null == jedisCluster || null == cacheKeyTO) {
return;
}
String cacheKey=cacheKeyTO.getCacheKey();
if(null == cacheKey || cacheKey.length() == 0) {
return;
}
ShardedJedis shardedJedis=null;
try {
int expire=result.getExpire();
String hfield=cacheKeyTO.getHfield();
if(null == hfield || hfield.length() == 0) {
if(expire == 0) {

jedisCluster.set(keySerializer.serialize(cacheKey), getSerializer().serialize(result));
} else {
jedisCluster.setex(keySerializer.serialize(cacheKey), expire, getSerializer().serialize(result));
}
} else {
hashSet(cacheKey, hfield, result);
}
} catch(Exception ex) {
logger.error(ex.getMessage(), ex);
} finally {
returnResource(shardedJedis);
}
}

private void hashSet(String cacheKey, String hfield, CacheWrapper<Object> result) throws Exception {
byte[] key=keySerializer.serialize(cacheKey);
byte[] field=keySerializer.serialize(hfield);
byte[] val=getSerializer().serialize(result);
int hExpire;
if(hashExpire < 0) {
hExpire=result.getExpire();
} else {
hExpire=hashExpire;
}
if(hExpire == 0) {
jedisCluster.hset(key, field, val);
} else {
jedisCluster.hset(key, field, val);
jedisCluster.expire(key, hExpire);
}
}

@SuppressWarnings("unchecked")
@Override
public CacheWrapper<Object> get(final CacheKeyTO cacheKeyTO, final Method method, final Object args[]) throws CacheCenterConnectionException {
if(null == jedisCluster || null == cacheKeyTO) {
return null;
}
String cacheKey=cacheKeyTO.getCacheKey();
if(null == cacheKey || cacheKey.length() == 0) {
return null;
}
CacheWrapper<Object> res=null;
ShardedJedis shardedJedis=null;
try {
byte bytes[]=null;
String hfield=cacheKeyTO.getHfield();
if(null == hfield || hfield.length() == 0) {
bytes=jedisCluster.get(keySerializer.serialize(cacheKey));
} else {
bytes=jedisCluster.hget(keySerializer.serialize(cacheKey), keySerializer.serialize(hfield));
}
Type returnType=method.getGenericReturnType();
res=(CacheWrapper<Object>)getSerializer().deserialize(bytes, returnType);
} catch(Exception ex) {
logger.error(ex.getMessage(), ex);
} finally {
returnResource(shardedJedis);
}
return res;
}

/**
* 根据缓存Key删除缓存
* @param cacheKeyTO 缓存Key
*/
@Override
public void delete(CacheKeyTO cacheKeyTO) throws CacheCenterConnectionException {
if(null == jedisCluster || null == cacheKeyTO) {
return;
}
String cacheKey=cacheKeyTO.getCacheKey();
if(null == cacheKey || cacheKey.length() == 0) {
return;
}
logger.debug("delete cache:" + cacheKey);
try {
String hfield=cacheKeyTO.getHfield();
if(null == hfield || hfield.length() == 0) {
jedisCluster.del(keySerializer.serialize(cacheKey));
} else {
jedisCluster.hdel(keySerializer.serialize(cacheKey), keySerializer.serialize(hfield));
}
this.getAutoLoadHandler().resetAutoLoadLastLoadTime(cacheKeyTO);
} catch(Exception ex) {
logger.error(ex.getMessage(), ex);
} finally {
}
}

public JedisCluster getJedisCluster() {
return jedisCluster;
}

public void setJedisCluster(JedisCluster jedisCluster) {
this.jedisCluster=jedisCluster;
}

public int getHashExpire() {
return hashExpire;
}

public void setHashExpire(int hashExpire) {
if(hashExpire < 0) {
return;
}
this.hashExpire=hashExpire;
}

public boolean isHashExpireByScript() {
return hashExpireByScript;
}

public void setHashExpireByScript(boolean hashExpireByScript) {
this.hashExpireByScript=hashExpireByScript;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -64,17 +64,15 @@ public boolean equals(Object paramObject) {
Type localType1=localParameterizedType.getOwnerType();
Type localType2=localParameterizedType.getRawType();

return (this.ownerType == null ? localType1 == null : this.ownerType.equals(localType1))
&& (this.rawType == null ? localType2 == null : this.rawType.equals(localType2))
return (this.ownerType == null ? localType1 == null : this.ownerType.equals(localType1)) && (this.rawType == null ? localType2 == null : this.rawType.equals(localType2))
&& (Arrays.equals(this.actualTypeArguments, localParameterizedType.getActualTypeArguments()));
}

return false;
}

public int hashCode() {
return Arrays.hashCode(this.actualTypeArguments) ^ (this.ownerType == null ? 0 : this.ownerType.hashCode())
^ (this.rawType == null ? 0 : this.rawType.hashCode());
return Arrays.hashCode(this.actualTypeArguments) ^ (this.ownerType == null ? 0 : this.ownerType.hashCode()) ^ (this.rawType == null ? 0 : this.rawType.hashCode());
}

public String toString() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@
import java.nio.charset.Charset;

/**
* Simple String to byte[] (and back) serializer. Converts Strings into bytes and vice-versa using the specified charset (by default
* UTF-8).
* Simple String to byte[] (and back) serializer. Converts Strings into bytes and vice-versa using the specified charset (by default UTF-8).
* <p>
* Useful when the interaction with the Redis happens mainly through Strings.
* </p>
Expand Down
5 changes: 2 additions & 3 deletions src/main/java/com/jarvis/lib/util/BeanUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,8 @@ public class BeanUtil {
* @return boolean true or false
*/
public static boolean isPrimitive(Object obj) {
boolean rv=obj.getClass().isPrimitive() || obj instanceof String || obj instanceof Integer || obj instanceof Long || obj instanceof Byte
|| obj instanceof Character || obj instanceof Boolean || obj instanceof Short || obj instanceof Float || obj instanceof Double || obj instanceof BigDecimal
|| obj instanceof BigInteger;
boolean rv=obj.getClass().isPrimitive() || obj instanceof String || obj instanceof Integer || obj instanceof Long || obj instanceof Byte || obj instanceof Character || obj instanceof Boolean
|| obj instanceof Short || obj instanceof Float || obj instanceof Double || obj instanceof BigDecimal || obj instanceof BigInteger;
return rv;
}

Expand Down

0 comments on commit ed35069

Please sign in to comment.