
com.github.knightliao.apollo.redis.RedisClient Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of apollo Show documentation
Show all versions of apollo Show documentation
https://github.com/knightliao/apollo
The newest version!
package com.github.knightliao.apollo.redis;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.pool.impl.GenericObjectPool;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.github.knightliao.apollo.redis.config.RedisHAClientConfig;
import com.github.knightliao.apollo.utils.data.JsonUtils;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.Protocol;
import redis.clients.util.SafeEncoder;
/**
* 封装Jedis API,提供redis命令调用的操作
*/
public class RedisClient implements RedisOperation {
protected final Logger logger = LoggerFactory.getLogger(this.getClass());
private String cacheName = "default";
private String redisServerHost = "localhost";
private int redisServerPort = Protocol.DEFAULT_PORT;
private String redisAuthKey;
private JedisPool jedisPool;
private boolean isAlive = true;
private int timeout = Protocol.DEFAULT_TIMEOUT;
private int maxIdle = GenericObjectPool.DEFAULT_MAX_IDLE;
private long maxWait = GenericObjectPool.DEFAULT_MAX_WAIT;
private boolean testOnBorrow = GenericObjectPool.DEFAULT_TEST_ON_BORROW;
private int minIdle = GenericObjectPool.DEFAULT_MIN_IDLE;
private int maxActive = GenericObjectPool.DEFAULT_MAX_ACTIVE;
private boolean testOnReturn = GenericObjectPool.DEFAULT_TEST_ON_RETURN;
private boolean testWhileIdle = GenericObjectPool.DEFAULT_TEST_WHILE_IDLE;
private long timeBetweenEvictionRunsMillis = GenericObjectPool.DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS;
private int numTestsPerEvictionRun = GenericObjectPool.DEFAULT_NUM_TESTS_PER_EVICTION_RUN;
private long minEvictableIdleTimeMillis = GenericObjectPool.DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS;
private long softMinEvictableIdleTimeMillis = GenericObjectPool.DEFAULT_SOFT_MIN_EVICTABLE_IDLE_TIME_MILLIS;
private boolean lifo = GenericObjectPool.DEFAULT_LIFO;
private byte whenExhaustedAction = GenericObjectPool.WHEN_EXHAUSTED_BLOCK;
/**
* Creates a new instance of RedisClient.
*/
public RedisClient(RedisHAClientConfig clientConfig) {
if (clientConfig == null) {
throw new IllegalArgumentException("Client config is null");
}
this.cacheName = clientConfig.getCacheName();
this.redisServerHost = clientConfig.getRedisServerHost();
this.redisServerPort = clientConfig.getRedisServerPort();
this.timeout = clientConfig.getTimeout();
this.redisAuthKey = clientConfig.getRedisAuthKey();
if (StringUtils.isEmpty(redisAuthKey)) {
logger.info("use no auth mode for " + redisServerHost);
jedisPool = new JedisPool(getPoolConfig(), redisServerHost, redisServerPort, timeout);
} else {
jedisPool = new JedisPool(getPoolConfig(), redisServerHost, redisServerPort, timeout, redisAuthKey);
}
onAfterInit(redisServerHost, redisServerPort);
}
protected void onAfterInit(String host, int port) {
logger.info("New Jedis pool object created. Connection pool will be initiated when calling.");
}
private GenericObjectPool.Config getPoolConfig() {
GenericObjectPool.Config poolConfig = new GenericObjectPool.Config();
// maxIdle为负数时,不对pool size大小做限制,此处做限制,防止保持过多空闲redis连接
if (this.maxIdle >= 0) {
poolConfig.maxIdle = this.maxIdle;
}
poolConfig.maxWait = this.maxWait;
if (this.whenExhaustedAction >= 0 && this.whenExhaustedAction < 3) {
poolConfig.whenExhaustedAction = this.whenExhaustedAction;
}
poolConfig.testOnBorrow = this.testOnBorrow;
poolConfig.minIdle = this.minIdle;
poolConfig.maxActive = this.maxActive;
poolConfig.testOnReturn = this.testOnReturn;
poolConfig.testWhileIdle = this.testWhileIdle;
poolConfig.timeBetweenEvictionRunsMillis = this.timeBetweenEvictionRunsMillis;
poolConfig.numTestsPerEvictionRun = this.numTestsPerEvictionRun;
poolConfig.minEvictableIdleTimeMillis = this.minEvictableIdleTimeMillis;
poolConfig.softMinEvictableIdleTimeMillis = this.softMinEvictableIdleTimeMillis;
poolConfig.lifo = this.lifo;
return poolConfig;
}
public String ping() {
Jedis jedis = null;
try {
jedis = this.jedisPool.getResource();
String pong = jedis.ping();
return pong;
} catch (Exception e) {
logger.debug(e.getMessage());
this.jedisPool.returnBrokenResource(jedis);
} finally {
if (jedis != null) {
this.jedisPool.returnResource(jedis);
}
}
return StringUtils.EMPTY;
}
/**
* get old value and set new value
*
* @param key
* @param value
* @param expiration
*
* @return false if redis did not execute the option
*
* @throws Exception
* @author wangchongjie
*/
public Object getSet(String key, Object value, Integer expiration) throws Exception {
Jedis jedis = null;
try {
jedis = this.jedisPool.getResource();
long begin = System.currentTimeMillis();
// 操作expire成功返回1,失败返回0,仅当均返回1时,实际操作成功
byte[] val = jedis.getSet(SafeEncoder.encode(key), serialize(value));
Object result = deserialize(val);
boolean success = true;
if (expiration > 0) {
Long res = jedis.expire(key, expiration);
if (res == 0L) {
success = false;
}
}
long end = System.currentTimeMillis();
if (success) {
logger.info("getset key:" + key + ", spends: " + (end - begin) + "ms");
} else {
logger.info("getset key: " + key + " failed, key has already exists! ");
}
return result;
} catch (Exception e) {
logger.error(e.getMessage(), e);
this.jedisPool.returnBrokenResource(jedis);
throw e;
} finally {
if (jedis != null) {
this.jedisPool.returnResource(jedis);
}
}
}
/**
* get value
* return null if key did not exist
*
* @param key
*
* @return
*
* @throws Exception
*/
public Object get(String key) throws Exception {
byte[] data = null;
Jedis jedis = null;
try {
jedis = this.jedisPool.getResource();
long begin = System.currentTimeMillis();
data = jedis.get(SafeEncoder.encode(key));
long end = System.currentTimeMillis();
logger.info("get key:" + key + ", spends: " + (end - begin) + "ms");
} catch (Exception e) {
// do jedis.quit() and jedis.disconnect()
this.jedisPool.returnBrokenResource(jedis);
throw e;
} finally {
if (jedis != null) {
this.jedisPool.returnResource(jedis);
}
}
return this.deserialize(data);
}
/**
* value set
* The string can't be longer than 1073741824 bytes (1 GB).
*
* @param key
* @param value
* @param expiration
*
* @return false if redis did not execute the option
*/
public boolean set(String key, Object value, Integer expiration) throws Exception {
String result = "";
Jedis jedis = null;
try {
jedis = this.jedisPool.getResource();
long begin = System.currentTimeMillis();
if (expiration > 0) {
result = jedis.setex(SafeEncoder.encode(key), expiration, serialize(value));
} else {
result = jedis.set(SafeEncoder.encode(key), serialize(value));
}
long end = System.currentTimeMillis();
logger.info("set key:" + key + ", spends: " + (end - begin) + "ms");
return "OK".equalsIgnoreCase(result);
} catch (Exception e) {
logger.error(e.getMessage(), e);
this.jedisPool.returnBrokenResource(jedis);
throw e;
} finally {
if (jedis != null) {
this.jedisPool.returnResource(jedis);
}
}
}
/**
* set a value without expiration
*
* @param key
* @param value
*
* @return false if redis did not execute the option
*
* @throws Exception
*/
public boolean set(String key, Object value) throws Exception {
return this.set(key, value, -1);
}
/**
* add if not exists
*
* @param key
* @param value
* @param expiration
*
* @return false if redis did not execute the option
*
* @throws Exception
*/
public boolean add(String key, Object value, Integer expiration) throws Exception {
Jedis jedis = null;
try {
jedis = this.jedisPool.getResource();
long begin = System.currentTimeMillis();
// 操作setnx与expire成功返回1,失败返回0,仅当均返回1时,实际操作成功
Long result = jedis.setnx(SafeEncoder.encode(key), serialize(value));
if (expiration > 0) {
result = result & jedis.expire(key, expiration);
}
long end = System.currentTimeMillis();
if (result == 1L) {
logger.info("add key:" + key + ", spends: " + (end - begin) + "ms");
} else {
logger.info("add key: " + key + " failed, key has already exists! ");
}
return result == 1L;
} catch (Exception e) {
logger.error(e.getMessage(), e);
this.jedisPool.returnBrokenResource(jedis);
throw e;
} finally {
if (jedis != null) {
this.jedisPool.returnResource(jedis);
}
}
}
/**
* add if not exists
*
* @param key
* @param value
*
* @return false if redis did not execute the option
*
* @throws Exception
*/
public boolean add(String key, Object value) throws Exception {
return this.add(key, value, -1);
}
/**
* Test if the specified key exists.
*
* @param key
*
* @return
*
* @throws Exception
*/
public boolean exists(String key) throws Exception {
boolean isExist = false;
Jedis jedis = null;
try {
jedis = this.jedisPool.getResource();
isExist = jedis.exists(SafeEncoder.encode(key));
} catch (Exception e) {
logger.error(e.getMessage(), e);
this.jedisPool.returnBrokenResource(jedis);
throw e;
} finally {
if (jedis != null) {
this.jedisPool.returnResource(jedis);
}
}
return isExist;
}
/**
* Remove the specified keys.
*
* @param key
*
* @return false if redis did not execute the option
*/
public boolean delete(String key) {
Jedis jedis = null;
try {
jedis = this.jedisPool.getResource();
jedis.del(SafeEncoder.encode(key));
logger.info("delete key:" + key);
return true;
} catch (Exception e) {
logger.error(e.getMessage(), e);
this.jedisPool.returnBrokenResource(jedis);
} finally {
if (jedis != null) {
this.jedisPool.returnResource(jedis);
}
}
return false;
}
/**
* Remove the specified keys.
*
* @param key
*
* @return false if redis did not execute the option
*/
public boolean expire(String key, int seconds) {
Jedis jedis = null;
try {
jedis = this.jedisPool.getResource();
jedis.expire(SafeEncoder.encode(key), seconds);
logger.info("expire key:" + key + " time after " + seconds + " seconds.");
return true;
} catch (Exception e) {
logger.error(e.getMessage(), e);
this.jedisPool.returnBrokenResource(jedis);
} finally {
if (jedis != null) {
this.jedisPool.returnResource(jedis);
}
}
return false;
}
/**
* Delete all the keys of all the existing databases, not just the currently selected one.
*
* @return false if redis did not execute the option
*/
public boolean flushall() {
String result = "";
Jedis jedis = null;
try {
jedis = this.jedisPool.getResource();
result = jedis.flushAll();
logger.info("redis client name: " + this.getCacheName() + " flushall.");
} catch (Exception e) {
logger.error(e.getMessage(), e);
this.jedisPool.returnBrokenResource(jedis);
} finally {
if (jedis != null) {
this.jedisPool.returnResource(jedis);
}
}
return "OK".equalsIgnoreCase(result);
}
public void shutdown() {
try {
this.jedisPool.destroy();
} catch (Exception e) {
logger.error(e.getMessage(), e);
}
}
/**
* Get the bytes representing the given serialized object.
*/
protected byte[] serialize(Object o) {
if (o == null) {
// throw new NullPointerException("Can't serialize null");
return new byte[0];
}
byte[] rv = null;
try {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream os = new ObjectOutputStream(bos);
os.writeObject(o);
os.close();
bos.close();
rv = bos.toByteArray();
} catch (IOException e) {
throw new IllegalArgumentException("Non-serializable object", e);
}
return rv;
}
/**
* Get the object represented by the given serialized bytes.
*/
protected Object deserialize(byte[] in) {
Object rv = null;
try {
if (in != null) {
ByteArrayInputStream bis = new ByteArrayInputStream(in);
ObjectInputStream is = new ObjectInputStream(bis);
rv = is.readObject();
is.close();
bis.close();
}
} catch (IOException e) {
logger.warn("Caught IOException decoding %d bytes of data", e);
} catch (ClassNotFoundException e) {
logger.warn("Caught CNFE decoding %d bytes of data", e);
}
return rv;
}
public void hput(String key, String field, Serializable fieldValue) throws Exception {
Jedis jedis = null;
try {
jedis = this.jedisPool.getResource();
jedis.hset(SafeEncoder.encode(key), SafeEncoder.encode(field), serialize(fieldValue));
logger.info("hset key:" + key + " field:" + field);
} catch (Exception e) {
logger.error(e.getMessage(), e);
this.jedisPool.returnBrokenResource(jedis);
throw e;
} finally {
if (jedis != null) {
this.jedisPool.returnResource(jedis);
}
}
}
public Object hget(String key, String field) {
Jedis jedis = null;
try {
jedis = this.jedisPool.getResource();
byte[] value = jedis.hget(SafeEncoder.encode(key), SafeEncoder.encode(field));
logger.info("hget key:" + key + " field:" + field);
return deserialize(value);
} catch (Exception e) {
logger.error(e.getMessage(), e);
this.jedisPool.returnBrokenResource(jedis);
} finally {
if (jedis != null) {
this.jedisPool.returnResource(jedis);
}
}
return null;
}
public boolean hdel(String key, String field) throws Exception {
Jedis jedis = null;
try {
jedis = this.jedisPool.getResource();
long value = jedis.hdel(SafeEncoder.encode(key), SafeEncoder.encode(field));
logger.info("hget key:" + key + ", field:" + field);
return value == 1;
} catch (Exception e) {
logger.error(e.getMessage(), e);
this.jedisPool.returnBrokenResource(jedis);
throw e;
} finally {
if (jedis != null) {
this.jedisPool.returnResource(jedis);
}
}
}
public Set hKeys(String key) throws Exception {
Jedis jedis = null;
try {
jedis = this.jedisPool.getResource();
Set hkeys = jedis.hkeys(SafeEncoder.encode(key));
logger.info("hkeys key:" + key);
if (CollectionUtils.isEmpty(hkeys)) {
return new HashSet(1);
} else {
Set keys = new HashSet(hkeys.size());
for (byte[] bb : hkeys) {
keys.add(SafeEncoder.encode(bb));
}
return keys;
}
} catch (Exception e) {
logger.error(e.getMessage(), e);
this.jedisPool.returnBrokenResource(jedis);
throw e;
} finally {
if (jedis != null) {
this.jedisPool.returnResource(jedis);
}
}
}
public List
© 2015 - 2025 Weber Informatics LLC | Privacy Policy