Commit 6db93494 by 李传峰

1,redis版本处理,2,全局mvc配置调整

parent 843a0922
package com.pcloud.common.core.aspect;
import com.pcloud.common.utils.DateUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RandomUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.util.ResourceUtils;
import redis.clients.util.JedisClusterCRC16;
import redis.clients.util.SafeEncoder;
import java.io.*;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
/**
* 添加监控,查看
*/
//@Component
//@Aspect
@Slf4j
public class JedisClusterAspect {
//需要统计的方法调用次数
private Map<String, ConcurrentHashMap<String, AtomicInteger>> solfDistributedMap = new ConcurrentHashMap<>();
private Map<String, ConcurrentHashMap<String, AtomicInteger>> tempMap = new ConcurrentHashMap<>();
private LFU<String, String> cache = new LFU<>(10000);
public JedisClusterAspect() {
//初始化redis操作
new PringLogThread().start();
}
@Pointcut("execution(* redis.clients.jedis.JedisCluster.*(..))")
public void pointcut() {
}
class PringLogThread extends Thread {
@Override
public void run() {
String path = getResourceBasePath() + File.separator + "redislog" + File.separator;
File file = new File(path);
if (!file.exists()) {
file.mkdirs();
}
while (true) {
BufferedWriter out = null;
try {
Thread.sleep(60*60 * 1000);
tempMap.putAll(solfDistributedMap);
solfDistributedMap.clear();
String fileName = "hotkey" + DateUtils.getYmdHmsTime() + ".log";
out = new BufferedWriter(new FileWriter(path + fileName));
for (Map.Entry<String, ConcurrentHashMap<String, AtomicInteger>> entry : tempMap.entrySet()) {
for (Map.Entry<String, AtomicInteger> childEntry : entry.getValue().entrySet()) {
out.write("key前缀:"+entry.getKey() + ",节点:" + childEntry.getKey());
out.write(",调用次数:" + childEntry.getValue());
out.newLine();
}
}
tempMap.clear();
Map<String, LFU<String, String>.HitRate> hotMap = cache.getHotKeyMap();
for (Map.Entry<String, LFU<String, String>.HitRate> entry : hotMap.entrySet()) {
LFU<String, String>.HitRate hitRate = entry.getValue();
out.write("key:" + hitRate.getKey() + ",槽位:" + hitRate.getV() + ",次数:" + hitRate.getHitCount());
out.newLine();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
out.close();
} catch (IOException e) {
}
}
}
}
}
@AfterReturning(value = "pointcut()", returning = "result")
public void afterReturning(JoinPoint joinPoint, Object result) {
String methodName = joinPoint.getSignature().getName();
Object[] obj = joinPoint.getArgs();
String key = obj[0].toString();
setSoltDistributed(key);
cache.put(key, getNodeName(key));
int randomInt = RandomUtils.nextInt(1,101);
//100里面1个数,小于等于10的概率就是10%
if(randomInt<10){
log.warn("采样hotkey methodName {} key {}",methodName,key);
}
if(key.startsWith("readercenter")){
log.warn("统计增长比较快的key methodName {} key {}",methodName,key);
}
}
private String getNodeName(String key){
int slot = JedisClusterCRC16.getSlot(SafeEncoder.encode(key));
String nodeName = "";
if (slot >= 0 && slot <= 4095) {
nodeName = "firstNode";
} else if (slot >= 4096 && slot <= 8191) {
nodeName = "secondNode";
} else if (slot >= 8192 && slot <= 12287) {
nodeName = "thirdNode";
} else if (slot > 12288 && slot <= 16383) {
nodeName = "fourthNode";
}
return nodeName;
}
/**
* 计算key的分布
*
* @param key
*/
private void setSoltDistributed(String key) {
String[] keys = key.split(":");
if (keys.length < 2) {
return;
}
String keyPrefix = key.substring(0, key.lastIndexOf(":"));
String nodeName = getNodeName(key);
ConcurrentHashMap<String, AtomicInteger> map = solfDistributedMap.get(keyPrefix);
if (map == null) {
map = new ConcurrentHashMap<String, AtomicInteger>();
solfDistributedMap.put(keyPrefix,map);
}
AtomicInteger count = map.get(nodeName);
if (count == null) {
count = new AtomicInteger(1);
} else {
count.getAndIncrement();
}
map.put(nodeName, count);
}
private static String getResourceBasePath() {
// 获取跟目录
File path = null;
try {
path = new File(ResourceUtils.getURL("classpath:").getPath());
} catch (FileNotFoundException e) {
// nothing to do
}
if (path == null || !path.exists()) {
path = new File("");
}
String pathStr = path.getAbsolutePath();
// 如果是在eclipse中运行,则和target同级目录,如果是jar部署到服务器,则默认和jar包同级
pathStr = pathStr.replace("\\target\\classes", "");
return pathStr;
}
public void addMissCount(ConcurrentHashMap<String, AtomicInteger> map, String key) {
AtomicInteger missCount = map.get(key);
if (missCount == null) {
missCount = new AtomicInteger(1);
} else {
missCount.getAndIncrement();
}
map.put(key, missCount);
}
}
...@@ -25,7 +25,12 @@ public class GlobalWebMvcConfigurerAdapter implements WebMvcConfigurer { ...@@ -25,7 +25,12 @@ public class GlobalWebMvcConfigurerAdapter implements WebMvcConfigurer {
/** /**
* 监控埋点日志拦截器,需要在第一个 * 监控埋点日志拦截器,需要在第一个
*/ */
registry.addInterceptor(new MonitorInterceptor(appCode)); registry.addInterceptor(new MonitorInterceptor(appCode))
.excludePathPatterns("/**/*.css", "/**/*.js",
"/**/*.jpg", "/**/*.png", "/**/*.gif", "/**/*.ico", "/**/*.tif", "/**/*.svg",
"/**/*.jpeg", "/**/*.bmp", "/**/*.tiff", "/**/*.wav", "/**/*.mp3", "/**/*.mp4",
"/**/*.html", "/**/*.htm"
);
registry.addInterceptor(new GlobalHandlerInterceptor()); registry.addInterceptor(new GlobalHandlerInterceptor());
} }
......
...@@ -2,7 +2,6 @@ package com.pcloud.common.core.mybatis.cache.redis; ...@@ -2,7 +2,6 @@ package com.pcloud.common.core.mybatis.cache.redis;
import redis.clients.jedis.Jedis; import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisSentinelPool; import redis.clients.jedis.JedisSentinelPool;
import redis.clients.jedis.exceptions.JedisConnectionException;
/** /**
* ClassName: CachePool <br/> * ClassName: CachePool <br/>
...@@ -43,20 +42,7 @@ public class CachePool { ...@@ -43,20 +42,7 @@ public class CachePool {
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
public Jedis getJedis() { public Jedis getJedis() {
Jedis jedis = null; return pool.getResource();
boolean borrowOrOprSuccess = true;
try {
jedis = pool.getResource();
} catch (JedisConnectionException e) {
borrowOrOprSuccess = false;
if (jedis != null)
pool.returnBrokenResource(jedis);
} finally {
if (borrowOrOprSuccess)
pool.returnResource(jedis);
}
jedis = pool.getResource();
return jedis;
} }
public JedisSentinelPool getJedisPool() { public JedisSentinelPool getJedisPool() {
......
package com.pcloud.common.core.mybatis.cache.redis; package com.pcloud.common.core.mybatis.cache.redis;
import java.util.concurrent.locks.ReadWriteLock; import com.pcloud.common.utils.cache.redis.SerializeUtils;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.apache.ibatis.cache.Cache; import org.apache.ibatis.cache.Cache;
import com.pcloud.common.utils.cache.redis.SerializeUtils;
import redis.clients.jedis.Jedis; import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisSentinelPool; import redis.clients.jedis.JedisSentinelPool;
import redis.clients.jedis.exceptions.JedisConnectionException; import redis.clients.jedis.exceptions.JedisConnectionException;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
/** /**
* @描述:Mybatis 接口 实现 redis 功能 类<br/> * @描述:Mybatis 接口 实现 redis 功能 类<br/>
* <per> * <per>
...@@ -51,26 +49,11 @@ public class RedisCache implements Cache { ...@@ -51,26 +49,11 @@ public class RedisCache implements Cache {
return this.id; return this.id;
} }
@SuppressWarnings("deprecation")
@Override @Override
public int getSize() { public int getSize() {
Jedis jedis = null; Jedis jedis = CachePool.getInstance().getJedis();
JedisSentinelPool jedisPool = null;
int result = 0; return Integer.parseInt(jedis.dbSize().toString());
boolean borrowOrOprSuccess = true;
try {
jedis = CachePool.getInstance().getJedis();
jedisPool = CachePool.getInstance().getJedisPool();
result = Integer.valueOf(jedis.dbSize().toString());
} catch (JedisConnectionException e) {
borrowOrOprSuccess = false;
if (jedis != null)
jedisPool.returnBrokenResource(jedis);
} finally {
if (borrowOrOprSuccess)
jedisPool.returnResource(jedis);
}
return result;
} }
...@@ -81,22 +64,12 @@ public class RedisCache implements Cache { ...@@ -81,22 +64,12 @@ public class RedisCache implements Cache {
log.debug("putObject:" + key.hashCode() + "=" + value); log.debug("putObject:" + key.hashCode() + "=" + value);
if (log.isInfoEnabled()) if (log.isInfoEnabled())
log.info("put to redis sql :" + key.toString()); log.info("put to redis sql :" + key.toString());
Jedis jedis = null;
JedisSentinelPool jedisPool = null;
boolean borrowOrOprSuccess = true; boolean borrowOrOprSuccess = true;
try { try {
jedis = CachePool.getInstance().getJedis(); Jedis jedis = CachePool.getInstance().getJedis();
jedisPool = CachePool.getInstance().getJedisPool();
jedis.set(SerializeUtils.serialize(key.hashCode()), SerializeUtils.serialize(value)); jedis.set(SerializeUtils.serialize(key.hashCode()), SerializeUtils.serialize(value));
} catch (JedisConnectionException e) {
borrowOrOprSuccess = false;
if (jedis != null)
jedisPool.returnBrokenResource(jedis);
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} finally {
if (borrowOrOprSuccess)
jedisPool.returnResource(jedis);
} }
} }
...@@ -110,20 +83,9 @@ public class RedisCache implements Cache { ...@@ -110,20 +83,9 @@ public class RedisCache implements Cache {
boolean borrowOrOprSuccess = true; boolean borrowOrOprSuccess = true;
try { try {
jedis = CachePool.getInstance().getJedis(); jedis = CachePool.getInstance().getJedis();
jedisPool = CachePool.getInstance().getJedisPool();
System.out.println(key.hashCode());
System.out.println(SerializeUtils.serialize(key.hashCode()));
System.out.println(jedis.get(SerializeUtils.serialize(key.hashCode())));
value = SerializeUtils.unSerialize(jedis.get(SerializeUtils.serialize(key.hashCode()))); value = SerializeUtils.unSerialize(jedis.get(SerializeUtils.serialize(key.hashCode())));
} catch (JedisConnectionException e) {
borrowOrOprSuccess = false;
if (jedis != null)
jedisPool.returnBrokenResource(jedis);
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} finally {
if (borrowOrOprSuccess)
jedisPool.returnResource(jedis);
} }
if (log.isDebugEnabled()) if (log.isDebugEnabled())
log.debug("getObject:" + key.hashCode() + "=" + value); log.debug("getObject:" + key.hashCode() + "=" + value);
...@@ -141,15 +103,8 @@ public class RedisCache implements Cache { ...@@ -141,15 +103,8 @@ public class RedisCache implements Cache {
jedis = CachePool.getInstance().getJedis(); jedis = CachePool.getInstance().getJedis();
jedisPool = CachePool.getInstance().getJedisPool(); jedisPool = CachePool.getInstance().getJedisPool();
value = jedis.expire(SerializeUtils.serialize(key.hashCode()), 0); value = jedis.expire(SerializeUtils.serialize(key.hashCode()), 0);
} catch (JedisConnectionException e) {
borrowOrOprSuccess = false;
if (jedis != null)
jedisPool.returnBrokenResource(jedis);
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} finally {
if (borrowOrOprSuccess)
jedisPool.returnResource(jedis);
} }
if (log.isDebugEnabled()) if (log.isDebugEnabled())
log.debug("getObject:" + key.hashCode() + "=" + value); log.debug("getObject:" + key.hashCode() + "=" + value);
...@@ -168,12 +123,7 @@ public class RedisCache implements Cache { ...@@ -168,12 +123,7 @@ public class RedisCache implements Cache {
jedis.flushDB(); jedis.flushDB();
jedis.flushAll(); jedis.flushAll();
} catch (JedisConnectionException e) { } catch (JedisConnectionException e) {
borrowOrOprSuccess = false; e.printStackTrace();
if (jedis != null)
jedisPool.returnBrokenResource(jedis);
} finally {
if (borrowOrOprSuccess)
jedisPool.returnResource(jedis);
} }
} }
......
...@@ -23,6 +23,7 @@ import com.pcloud.common.utils.string.StringUtil; ...@@ -23,6 +23,7 @@ import com.pcloud.common.utils.string.StringUtil;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
import redis.clients.jedis.JedisCluster; import redis.clients.jedis.JedisCluster;
import redis.clients.jedis.params.SetParams;
/** /**
* @描述:redis集群API * @描述:redis集群API
...@@ -160,7 +161,7 @@ public class JedisClusterUtils { ...@@ -160,7 +161,7 @@ public class JedisClusterUtils {
public static boolean set(String key, String value, String nxxx, String expx, Integer seconds) { public static boolean set(String key, String value, String nxxx, String expx, Integer seconds) {
try { try {
seconds = Optional.ofNullable(seconds).orElse(60); seconds = Optional.ofNullable(seconds).orElse(60);
String result = jedisCluster.set(key, value, nxxx, expx, seconds); String result = jedisCluster.set(key, value, SetParams.setParams().nx().ex(seconds));
return "OK".equalsIgnoreCase(result); return "OK".equalsIgnoreCase(result);
} catch (Exception e) { } catch (Exception e) {
LOGGER.warn("jedis缓存保存失败:" + e.getMessage(), e); LOGGER.warn("jedis缓存保存失败:" + e.getMessage(), e);
...@@ -174,7 +175,7 @@ public class JedisClusterUtils { ...@@ -174,7 +175,7 @@ public class JedisClusterUtils {
public static boolean lock(String key, Integer seconds) { public static boolean lock(String key, Integer seconds) {
try { try {
seconds = Optional.ofNullable(seconds).orElse(60); seconds = Optional.ofNullable(seconds).orElse(60);
String result = jedisCluster.set(key, String.valueOf(System.currentTimeMillis()), "NX", "EX", seconds); String result = jedisCluster.set(key, String.valueOf(System.currentTimeMillis()), SetParams.setParams().nx().ex(seconds));
return "OK".equalsIgnoreCase(result); return "OK".equalsIgnoreCase(result);
} catch (Exception e) { } catch (Exception e) {
LOGGER.warn("jedis缓存保存失败:" + e.getMessage(), e); LOGGER.warn("jedis缓存保存失败:" + e.getMessage(), e);
...@@ -186,8 +187,8 @@ public class JedisClusterUtils { ...@@ -186,8 +187,8 @@ public class JedisClusterUtils {
/** /**
* 保存一个字符串到redis中,长期有效 * 保存一个字符串到redis中,长期有效
* *
* @param objecKey 键 * @param key 键
* @param objecValue 缓存对象 * @param value 缓存对象
* @return * @return
*/ */
public static boolean setObject(Object key, Object value) { public static boolean setObject(Object key, Object value) {
...@@ -203,8 +204,8 @@ public class JedisClusterUtils { ...@@ -203,8 +204,8 @@ public class JedisClusterUtils {
/** /**
* 保存一个字符串到redis中并指定过期时间 * 保存一个字符串到redis中并指定过期时间
* *
* @param objecKey 键 * @param key 键
* @param objecValue 缓存对象 * @param value 缓存对象
* @param seconds 时间,如果为null,则使用默认时间30分钟 * @param seconds 时间,如果为null,则使用默认时间30分钟
* @return * @return
*/ */
...@@ -275,7 +276,7 @@ public class JedisClusterUtils { ...@@ -275,7 +276,7 @@ public class JedisClusterUtils {
/** /**
* 根据缓存键获取Redis缓存中的对象.<br/> * 根据缓存键获取Redis缓存中的对象.<br/>
* *
* @param objecKey 键 * @param key 键
* @return * @return
*/ */
public static Object getObject(Object key) { public static Object getObject(Object key) {
...@@ -501,7 +502,6 @@ public class JedisClusterUtils { ...@@ -501,7 +502,6 @@ public class JedisClusterUtils {
* 根据缓存键获取Redis缓存中的Map.<br/> * 根据缓存键获取Redis缓存中的Map.<br/>
* *
* @param key * @param key
* @param fields 具体的map键
* @return * @return
*/ */
public static Map<String, String> hgetAll(String key) { public static Map<String, String> hgetAll(String key) {
...@@ -614,7 +614,6 @@ public class JedisClusterUtils { ...@@ -614,7 +614,6 @@ public class JedisClusterUtils {
* 根据缓存键删除map中的指定键值 * 根据缓存键删除map中的指定键值
* *
* @param key 缓存键 * @param key 缓存键
* @param field map键值
* @return 删除成功返回1,失败返回0 * @return 删除成功返回1,失败返回0
*/ */
public static Boolean hdel(String key, String... fields) { public static Boolean hdel(String key, String... fields) {
...@@ -712,7 +711,6 @@ public class JedisClusterUtils { ...@@ -712,7 +711,6 @@ public class JedisClusterUtils {
* 添加内容到指定key的list中,先进后出(左放置) * 添加内容到指定key的list中,先进后出(左放置)
* *
* @param key * @param key
* @param field
* @param value * @param value
* @return * @return
*/ */
...@@ -764,7 +762,6 @@ public class JedisClusterUtils { ...@@ -764,7 +762,6 @@ public class JedisClusterUtils {
* 添加内容到指定key的list中,先进先出(从右放置) * 添加内容到指定key的list中,先进先出(从右放置)
* *
* @param key * @param key
* @param field
* @param value * @param value
* @return * @return
*/ */
...@@ -799,7 +796,6 @@ public class JedisClusterUtils { ...@@ -799,7 +796,6 @@ public class JedisClusterUtils {
* 添加内容到指定key的list中,先进先出(从右放置) * 添加内容到指定key的list中,先进先出(从右放置)
* *
* @param key * @param key
* @param field
* @param value * @param value
* @return * @return
*/ */
...@@ -1013,7 +1009,7 @@ public class JedisClusterUtils { ...@@ -1013,7 +1009,7 @@ public class JedisClusterUtils {
} }
return null; return null;
} }
/** /**
* 删除指定元素 * 删除指定元素
* 该命令用于从key对应的list中,移除前count次出现 的值为value的元素。count参数有三种情况: * 该命令用于从key对应的list中,移除前count次出现 的值为value的元素。count参数有三种情况:
...@@ -1173,7 +1169,7 @@ public class JedisClusterUtils { ...@@ -1173,7 +1169,7 @@ public class JedisClusterUtils {
* 根据clazz和key获取对应的map * 根据clazz和key获取对应的map
* *
* @param key * @param key
* @param clazz * @param vClazz
* @return * @return
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
......
...@@ -46,11 +46,6 @@ ...@@ -46,11 +46,6 @@
<version>1.10.10</version> <version>1.10.10</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.10.2</version>
</dependency>
<dependency>
<groupId>commons-lang</groupId> <groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId> <artifactId>commons-lang</artifactId>
<version>2.6</version> <version>2.6</version>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment