1. 程式人生 > >spring-shiro-reids 叢集採用redis做session儲存

spring-shiro-reids 叢集採用redis做session儲存

package com.iss.rdp.extension.web.shiro.cluster;


import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;


import org.apache.shiro.cache.Cache;
import org.apache.shiro.cache.CacheException;
import org.apache.shiro.util.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
public class RedisCache
<K,V> implements Cache<K,V> {  
  
    private Logger logger = LoggerFactory.getLogger(this.getClass());  
      
    /** 
     * The wrapped Jedis instance. 
     */  
    private RedisManager cache;  
      
    /** 
     * The Redis key prefix for the sessions  
     */  
    private String keyPrefix = "shiro_redis_session:";  
      
    /** 
     * Returns the Redis session keys 
     * prefix. 
     * @return The prefix 
     */  
    public String getKeyPrefix() {  
        return keyPrefix;  
    }  
  
    /** 
     * Sets the Redis sessions key  
     * prefix. 
     * @param keyPrefix The prefix 
     */  
    public void setKeyPrefix(String keyPrefix) {  
        this.keyPrefix = keyPrefix;  
    }  
      
    /** 
     * 通過一個JedisManager例項構造RedisCache 
     */  
    public RedisCache(RedisManager cache){  
         if (cache == null) {  
             throw new IllegalArgumentException("Cache argument cannot be null.");  
         }  
         this.cache = cache;  
    }  
      
    /** 
     * Constructs a cache instance with the specified 
     * Redis manager and using a custom key prefix. 
     * @param cache The cache manager instance 
     * @param prefix The Redis key prefix 
     */  
    public RedisCache(RedisManager cache, String prefix){  
           
        this( cache );  
          
        // set the prefix  
        this.keyPrefix = prefix;  
    }  
      
    /** 
     * 獲得byte[]型的key 
     * @param key 
     * @return 
     */  
    private byte[] getByteKey(K key){  
        if(key instanceof String){  
            String preKey = this.keyPrefix + key;  
            return preKey.getBytes();  
        }else{  
            return SerializeUtils.serialize(key);  
        }  
    }  
      
    @Override  
    public V get(K key) throws CacheException {  
        logger.debug("根據key從Redis中獲取物件 key [" + key + "]");  
        try {  
            if (key == null) {  
                return null;  
            }else{  
                byte[] rawValue = cache.get(getByteKey(key));  
                //String rawValue = cache.get(key);  
                @SuppressWarnings("unchecked")  
                V value = (V)SerializeUtils.deserialize(rawValue);  
                return value;  
            }  
        } catch (Throwable t) {  
            throw new CacheException(t);  
        }  
  
    }  
  
    @Override  
    public V put(K key, V value) throws CacheException {  
        logger.debug("根據key從儲存 key [" + key + "]");  
         try {  
                cache.set(getByteKey(key), SerializeUtils.serialize(value));  
                return value;  
            } catch (Throwable t) {  
                throw new CacheException(t);  
            }  
    }  
  
    @Override  
    public V remove(K key) throws CacheException {  
        logger.debug("從redis中刪除 key [" + key + "]");  
        try {  
            V previous = get(key);  
            cache.del(getByteKey(key));  
            return previous;  
        } catch (Throwable t) {  
            throw new CacheException(t);  
        }  
    }  
  
    @Override  
    public void clear() throws CacheException {  
        logger.debug("從redis中刪除所有元素");  
        try {  
            cache.flushDB();  
        } catch (Throwable t) {  
            throw new CacheException(t);  
        }  
    }  
  
    @Override  
    public int size() {  
        try {  
            Long longSize = new Long(cache.dbsize());  
            return longSize.intValue();  
        } catch (Throwable t) {  
            throw new CacheException(t);  
        }  
    }  
  
    @SuppressWarnings("unchecked")  
    @Override  
    public Set<K> keys() {  
        try {  
            Set<byte[]> keys = cache.keys(this.keyPrefix + "*");  
            if (CollectionUtils.isEmpty(keys)) {  
                return Collections.emptySet();  
            }else{  
                Set<K> newKeys = new HashSet<K>();  
                for(byte[] key:keys){  
                    newKeys.add((K)key);  
                }  
                return newKeys;  
            }  
        } catch (Throwable t) {  
            throw new CacheException(t);  
        }  
    }  
  
    @Override  
    public Collection<V> values() {  
        try {  
            Set<byte[]> keys = cache.keys(this.keyPrefix + "*");  
            if (!CollectionUtils.isEmpty(keys)) {  
                List<V> values = new ArrayList<V>(keys.size());  
                for (byte[] key : keys) {  
                    @SuppressWarnings("unchecked")  
                    V value = get((K)key);  
                    if (value != null) {  
                        values.add(value);  
                    }  
                }  
                return Collections.unmodifiableList(values);  
            } else {  
                return Collections.emptyList();  
            }  
        } catch (Throwable t) {  
            throw new CacheException(t);  
        }  
    }  

}  




package com.iss.rdp.extension.web.shiro.cluster;


import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;


import org.apache.shiro.cache.CacheException;
import org.apache.shiro.cache.CacheManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;


import net.sf.ehcache.Cache;
public class RedisCacheManager

<K, V>  implements CacheManager{  
  
    private static final Logger logger = LoggerFactory  
            .getLogger(RedisCacheManager.class);  
  
    // fast lookup by name map  
    private final ConcurrentMap<String, RedisCache> caches = new ConcurrentHashMap<String, RedisCache>();  
    private RedisManager redisManager;  
  
    /** 
     * The Redis key prefix for caches  
     */  
    private String keyPrefix = "shiro_redis_cache:";  
      
    /** 
     * Returns the Redis session keys 
     * prefix. 
     * @return The prefix 
     */  
    public String getKeyPrefix() {  
        return keyPrefix;  
    }  
  
    /** 
     * Sets the Redis sessions key  
     * prefix. 
     * @param keyPrefix The prefix 
     */  
    public void setKeyPrefix(String keyPrefix) {  
        this.keyPrefix = keyPrefix;  
    }  
      
    @Override  
    public  RedisCache<K, V> getCache(String name) throws CacheException {  
        logger.debug("獲取名稱為: " + name + " 的RedisCache例項");  
          
        RedisCache c = caches.get(name);  
          
        if (c == null) {  
  
            // initialize the Redis manager instance  
           // redisManager.init();  
              
            // create a new cache instance  
            c = new RedisCache(redisManager, keyPrefix);  
              
            // add it to the cache collection  
            caches.put(name, c);  
        }  
        return c;  
    }  
  
    public RedisManager getRedisManager() {  
        return redisManager;  
    }  
  
    public void setRedisManager(RedisManager redisManager) {  
        this.redisManager = redisManager;  
    }  

}  



package com.iss.rdp.extension.web.shiro.cluster;


import java.util.List;
import java.util.Map;
import java.util.Set;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;


import groovy.util.logging.Commons;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.SortingParams;
public class RedisManager<K> {
@Autowired
private RedisPool redisPool;

public int getExpire() {
return redisPool.getExpire();
}
    public Jedis getJedis() {
        return redisPool.getInstance();
    }


    public void releaseJedis(Jedis jedis) {
        redisPool.returnResource(jedis);
    }


    public void releaseBrokenJedis(Jedis jedis) {
        redisPool.returnBrokenResource(jedis);
    }
    
    /**hash
     * 通過key給field設定指定的值,如果key不存在,則先建立 ,存在會覆蓋原來的值
     * @param key
     * @param field欄位
     * @param value
     * @return 如果不存在,新建的返回1,存在返回0, 異常返回null
     * 
     */
    public Long hset(String key, String field, String value) {
        Jedis jedis = getJedis();
        Long result = jedis.hset(key, field, value);
        releaseJedis(jedis);
        return result;
    }
    /**Hash
     * 為雜湊表 key 中的域 field 的值加上增量 value
     * @param key
     * @param field
     * @param value
     * @return
     */
    public Long hincrBy(String key, String field, long value) {
        Jedis jedis = getJedis();
        Long result = jedis.hincrBy(key, field, value);
        releaseJedis(jedis);
        return result;
    }


    /**


     * 通過key給field設定指定的值,如果key不存在則先建立,如果field已經存在,操作無效
     * @param key
     * @param field
     * @param value
     * @return 不存在新建返回1,存在返回0
     */
    public Long hsetnx(String key, String field, String value) {
        Jedis jedis = getJedis();
        Long result = jedis.hsetnx(key, field, value);
        releaseJedis(jedis);
        return result;
    }


    /**
     * 通過key同時設定 hash的多個field
     * @param key
     * @param hash
     * @return 返回OK 異常返回null
     */
    public String hmset(String key, Map<String, String> hash) {
        Jedis jedis = getJedis();
        String result = jedis.hmset(key, hash);
        releaseJedis(jedis);
        return result;
    }


    /**
     * 通過key 和 field 獲取指定的 value
     * @param key
     * @param field
     * @return 沒有返回null
     */
    public String hget(String key, String field) {
        Jedis jedis = getJedis();
        String result = jedis.hget(key, field);
        releaseJedis(jedis);
        return result;
    }


    /**
     * 通過key 和 fields 獲取指定的value 如果沒有對應的value則返回null
     * @param key
     * @param fields可以使 一個String 也可以是 String陣列
     * @return
     */
    public List<String> hmget(String key, String... fields) {
        Jedis jedis = getJedis();
        List<String> result = jedis.hmget(key, fields);
        releaseJedis(jedis);
        return result;
    }


    /**
     * 通過key獲取所有的field和value
     * @param key
     * @return
     */
    public Map<String, String> hgetAll(String key) {
        Jedis jedis = getJedis();
        Map<String, String> result = jedis.hgetAll(key);
        releaseJedis(jedis);
        return result;
    }
    /**
     * 通過key刪除field的value
     * @param key
     * @return
     */
    public Long hdel(String key, String field) {
        Jedis jedis = getJedis();
        Long result = jedis.hdel(key, field);
        releaseJedis(jedis);
        return result;
    }
    /**
     * 返回key為鍵中存放的field值的個數
     * @param key
     * @return 
     */
    public Long hlen(String key) {
        Jedis jedis = getJedis();
        Long result = jedis.hlen(key);
        releaseJedis(jedis);
        return result;
    }
    /**
     * 檢視key是否存在指定的field
     * @param key
     * @return 
     */
    public Boolean hexists(String key, String field) {
        Jedis jedis = getJedis();
        Boolean result = jedis.hexists(key, field);
        releaseJedis(jedis);
        return result;
    }


    /**
     * 返回key儲存的map物件中的所有key  
     * @param key
     * @return 
     */
    public Set<String> hkeys(String key) {
        Jedis jedis = getJedis();
        Set<String> result = jedis.hkeys(key);
        releaseJedis(jedis);
        return result;
    }
    /**
     * 返回key儲存的map物件中的所有鍵的values值  
     * @param key
     * @return 
     */
    public List<String> hvals(String key) {
        Jedis jedis = getJedis();
        List<String> result = jedis.hvals(key);
        releaseJedis(jedis);
        return result;
    }


    /**
     * 判斷key是否存在
     * @param key
     * @return true OR false
     */
    public boolean exists(String key) {
        Jedis jedis = null;
        boolean result = false;
        try {
            jedis = getJedis();
            result = jedis.exists(key);
        } catch (Exception e) {
            releaseBrokenJedis(jedis);
            e.printStackTrace();
        } finally {
            releaseJedis(jedis);
        }


        return result;
    }


    /**
     * 刪除指定的key,也可以傳入一個包含key的陣列
     * @param keys
     * @return 返回刪除成功的個數
     */
    public Long del(byte[]... keys) {
        Jedis jedis = null;
        Long result = 0L;
        try {
            jedis = getJedis();
            result = jedis.del(keys);
        } catch (Exception e) {
            releaseBrokenJedis(jedis);
            e.printStackTrace();
            result = 0L;
        } finally {
            releaseJedis(jedis);
        }
        return result;
    }


    /**
     * 對key的對應value值排序
     * @return 
     */
    public List<String> sort(String key) {
        Jedis jedis = getJedis();
        List<String> result = jedis.sort(key);
        releaseJedis(jedis);
        return result;
    }
    /**
     * 將當前資料庫的 ke移動到給定的資料庫 db 當中
     * @return 
     */
    public Long move(String key, int dbIndex) {
        Jedis jedis = getJedis();
        Long result = jedis.move(key, dbIndex);
        releaseJedis(jedis);
        return result;
    }
    /**
     * 返回某個key元素的資料型別 ( none:不存在,string:字元,list,set,zset,hash)
     * @return 
     */
    public String type(String key) {
        Jedis jedis = getJedis();
        String result = jedis.type(key);
        releaseJedis(jedis);
        return result;
    }
    /**
     * 返回當前資料庫的key的總數
     * @return 
     */
    public Long dbsize() {
        Jedis jedis = getJedis();
        Long result = jedis.dbSize();
        releaseJedis(jedis);
        return result;
    }
    /**
     *設定某個key的過期時間(秒),(EXPIRE bruce 1000:設定bruce這個key1000秒後系統自動刪除)注意:如果在還沒有過期的時候,對值進行了改變,那麼那個值會被清除。
     * @return 
     */
    public Long expire(String key, int seconds) {
        Jedis jedis = getJedis();
        Long result = jedis.expire(key, seconds);
        releaseJedis(jedis);
        return result;
    }
    /**
     * EXPIREAT 的作用和 EXPIRE 類似,都用於為 key 設定生存時間。
     * 不同在於 EXPIREAT 命令接受的時間引數是 UNIX 時間戳(unix timestamp)。
     * @return 
     */


    public Long expireAt(String key, Long unixTime) {
        Jedis jedis = getJedis();
        Long result = jedis.expireAt(key, unixTime);
        releaseJedis(jedis);
        return result;
    }
    /**List
     * 通過key在list頭部新增值
     * @param key
     * @param value
     * @return 在 push 操作後的 list 長度。
     */
    public Long lpush(String key, String value) {
        Jedis jedis = getJedis();
        Long result = jedis.lpush(key, value);
        releaseJedis(jedis);
        return result;
    }
    /**List
     * 向存於 key 的列表的尾部插入所有指定的值。如果 key 不存在,那麼會建立一個空的列表然後再進行 push 操作。 
     * 當 key 儲存的不是一個列表,那麼會返回一個錯誤。
     * @param key
     * @param value
     * @return  在 push 操作後的列表長度
     */
    public Long rpush(String key, String value) {
        Jedis jedis = getJedis();
        Long result = jedis.rpush(key, value);
        releaseJedis(jedis);
        return result;
    }
    /**List
     * 獲取list的長度
     * @param key
     * @return 
     */
    public Long llen(String key) {
        Jedis jedis = getJedis();
        Long result = jedis.llen(key);
        releaseJedis(jedis);
        return result;
    }
    /**List
     * 返回儲存在 key 的列表裡指定範圍內的元素
     * @param key 
     * @parm start 開始位置
     * @param end 結束位置 -1表示最後一個
     * @return 
     */
    public List<String> lrange(String key, long start, long end) {
        Jedis jedis = getJedis();
        List<String> result = jedis.lrange(key, start, end);
        releaseJedis(jedis);
        return result;
    }
    /**List
     * 擷取(trim)一個已存在的 list,這樣 list 就會只包含指定範圍的指定元素
     * @param key 
     * @parm start 開始位置
     * @param end 結束位置 -1表示最後一個
     * @return 
     */


    public String ltrim(String key, long start, long end) {
        Jedis jedis = getJedis();
        String result = jedis.ltrim(key, start, end);
        releaseJedis(jedis);
        return result;
    }
    /**List
     * 通過key在list頭部新增值
     * 只有當 key 已經存在並且存著一個 list 的時候,在這個 key 下面的 list 的頭部插入 value。 與 LPUSH 相反,當 key 不存在的時候不會進行任何操作。
     * @param key
     * @param value
     * @return 在 push 操作後的 list 長度。
     */


    public Long lpushx(String key, String value) {
        Jedis jedis = getJedis();
        Long result = jedis.lpushx(key, value);
        releaseJedis(jedis);
        return result;
    }


    public Long rpushx(String key, String value) {
        Jedis jedis = getJedis();
        Long result = jedis.rpushx(key, value);
        releaseJedis(jedis);
        return result;
    }
    /**
     * 彈出 List 的第一個元素
     * @param key
     * @return
     */
    public String lpop(String key) {
        Jedis jedis = getJedis();
        String result = jedis.lpop(key);
        releaseJedis(jedis);
        return result;
    }


    public String rpop(String key) {
        Jedis jedis = getJedis();
        String result = jedis.rpop(key);
        releaseJedis(jedis);
        return result;
    }
    /**
     * 根據引數 COUNT 的值,移除列表中與引數 VALUE 相等的元素。
     * count > 0 : 從表頭開始向表尾搜尋,移除與 VALUE 相等的元素,數量為 COUNT 。
     * count < 0 : 從表尾開始向表頭搜尋,移除與 VALUE 相等的元素,數量為 COUNT 的絕對值。
     * count = 0 : 移除表中所有與 VALUE 相等的值。
     */


    public Long lrem(String key, long count, String value) {
        Jedis jedis = getJedis();
        Long result = jedis.lrem(key, count, value);
        releaseJedis(jedis);
        return result;
    }
    /**
     * 設定 index 位置的list元素的值為 value
     * @param key
     * @param index
     * @param value
     * @return
     */
    public String lset(String key, long index, String value) {
        Jedis jedis = getJedis();
        String result = jedis.lset(key, index, value);
        releaseJedis(jedis);
        return result;
    }
    /**
     * 返回列表 key 中,下標為 index 的元素。
     * @param key
     * @param index
     * @return
     */
    public String lindex(String key, long index) {
        Jedis jedis = getJedis();
        String result = jedis.lindex(key, index);
        releaseJedis(jedis);
        return result;
    }
   /**
    *命令 RPOPLPUSH 在一個原子時間內,執行以下兩個動作:
    *將列表 source 中的最後一個元素(尾元素)彈出,並返回給客戶端。
    *將 source 彈出的元素插入到列表 destination ,作為 destination 列表的的頭元素。
    *舉個例子,你有兩個列表 source 和 destination , source 列表有元素 a, b, c , destination 列表有元素 x, y, z ,
    *執行 RPOPLPUSH source destination 之後, source 列表包含元素 a, b , destination 列表包含元素 c, x, y, z ,
    *並且元素 c 會被返回給客戶端。
    * @param srcKey
    * @param dstKey
    * @return
    */
    public String rpoplpush(String srcKey, String dstKey) {
        Jedis jedis = getJedis();
        String result = jedis.rpoplpush(srcKey, dstKey);
        releaseJedis(jedis);
        return result;
    }
    /**
     * BRPOPLPUSH 是 RPOPLPUSH 的阻塞版本,當給定列表 source 不為空時, BRPOPLPUSH 的表現和 RPOPLPUSH 一樣。
     *當列表 source 為空時, BRPOPLPUSH 命令將阻塞連線,直到等待超時,或有另一個客戶端對 source 執行 LPUSH 或 RPUSH 命令為止。
     *超時引數 timeout 接受一個以秒為單位的數字作為值。超時引數設為 0 表示阻塞時間可以無限期延長(block indefinitely) 。
     * @param source
     * @param destination
     * @param timeout
     * @return
     */
    public String brpoplpush(String source, String destination, int timeout) {
        Jedis jedis = getJedis();
        String result = jedis.brpoplpush(source, destination, timeout);
        releaseJedis(jedis);
        return result;
    }




   /**
    * 將一個或多個 member 元素加入到集合 key 當中,已經存在於集合的 member 元素將被忽略(set不重複)。
    * 假如 key 不存在,則建立一個只包含 member 元素作成員的集合。
    * @param key
    * @param member
    * @return
    */
    public Long sadd(String key, String member) {
        Jedis jedis = getJedis();
        Long result = jedis.sadd(key, member);
        releaseJedis(jedis);
        return result;
    }
    /**
     * 移除集合 key 中的一個 member 元素,不存在的 member 元素會被忽略。
     * @param key
     * @param member
     * @return
     */
    public Long srem(String key, String member) {
        Jedis jedis = getJedis();
        Long result = jedis.srem(key, member);
        releaseJedis(jedis);
        return result;
    }
    /**
     * 返回集合 key 中的所有成員。
     * @param key
     * @return
     */
    public Set<String> smembers(String key) {
        Jedis jedis = getJedis();
        Set<String> result = jedis.smembers(key);
        releaseJedis(jedis);
        return result;
    }
     /**
      * 判斷 member 元素是否集合 key 的成員。
      * @param key
      * @param member
      * @return
      */
    public Boolean sismember(String key, String member) {
        Jedis jedis = getJedis();
        Boolean result = jedis.sismember(key, member);
        releaseJedis(jedis);
        return result;
    }
   /**
    * 返回集合 key集合中元素的數量)。
    * @param key
    * @return
    */
    public Long scard(String key) {
        Jedis jedis = getJedis();
        Long result = jedis.scard(key);
        releaseJedis(jedis);
        return result;
    }
    /**
     * 將 member 元素從 source 集合移動到 destination 集合。
     *SMOVE 是原子性操作。
     *如果 source 集合不存在或不包含指定的 member 元素,則 SMOVE 命令不執行任何操作,僅返回 0 。否則, member 元素從 source 集合中被移除,並新增到 destination 集合中去。
     *當 destination 集合已經包含 member 元素時, SMOVE 命令只是簡單地將 source 集合中的 member 元素刪除。
     *當 source 或 destination 不是集合型別時,返回一個錯誤。
     * @param srckey
     * @param dstkey
     * @param member
     * @return
     */
    public Long smove(String srckey, String dstkey, String member) {
        Jedis jedis = getJedis();
        Long result = jedis.smove(srckey, dstkey, member);
        releaseJedis(jedis);
        return result;
    }


    /**
     * 移除並返回集合中的一個隨機元素。
     * @param key
     * @return
     */
    public String spop(String key) {
        Jedis jedis = getJedis();
        String result = jedis.spop(key);
        releaseJedis(jedis);
        return result;
    }
     /**
      * 返回集合中的一個隨機元素
      * @param key
      * @return
      */
    public String srandmember(String key) {
        Jedis jedis = getJedis();
        String result = jedis.srandmember(key);
        releaseJedis(jedis);
        return result;
    }


    /**
     * 返回給定集合的交集。
     * @param keys
     * @return
     */
    public Set<String> sinter(String... keys) {
        Jedis jedis = getJedis();
        Set<String> result = jedis.sinter(keys);
        releaseJedis(jedis);
        return result;
    }
    /**
     * 類似於 SINTER 命令,但它將結果儲存到 destination 集合,而不是簡單地返回結果集
     * @param dstkey
     * @param keys
     * @return
     */
    public Long sinterstore(String dstkey, String... keys) {
        Jedis jedis = getJedis();
        Long result = jedis.sinterstore(dstkey, keys);
        releaseJedis(jedis);
        return result;
    }
   /**
    * 返回所有給定集合的並集
    * @param keys
    * @return
    */
    public Set<String> sunion(String... keys) {
        Jedis jedis = getJedis();
        Set<String> result = jedis.sunion(keys);
        releaseJedis(jedis);
        return result;
    }


    public Long sunionstore(String dstkey, String... keys) {
        Jedis jedis = getJedis();
        Long result = jedis.sunionstore(dstkey, keys);
        releaseJedis(jedis);
        return result;
    }
    /**
     * 返回所有給定集合之間的差集。
     * @param keys
     * @return
     */
    public Set<String> sdiff(String... keys) {
        Jedis jedis = getJedis();
        Set<String> result = jedis.sdiff(keys);
        releaseJedis(jedis);
        return result;
    }


    public Long sdiffstore(String dstkey, String... keys) {
        Jedis jedis = getJedis();
        Long result = jedis.sdiffstore(dstkey, keys);
        releaseJedis(jedis);
        return result;
    }
   /**server
    * 清空整個 Redis 伺服器的資料(刪除所有資料庫的所有 key )。
    * @return
    */
    public String flushAll() {
        Jedis jedis = getJedis();
        String result = jedis.flushAll();
        releaseJedis(jedis);
        return result;
    }
   /**
    * 清空當前資料庫中的所有 key。
    * @return
    */
    public String flushDB() {
        Jedis jedis = getJedis();
        String result = jedis.flushDB();
        releaseJedis(jedis);
        return result;
    }
    /** 
    *停止所有客戶端
    *如果有至少一個儲存點在等待,執行 SAVE 命令
    *如果 AOF 選項被開啟,更新 AOF 檔案
    * 關閉 redis 伺服器(server)
    * @return
    */


    public String shutdown() {
        Jedis jedis = getJedis();
        String result = jedis.shutdown();
        releaseJedis(jedis);
        return result;
    }


    /**sorted set
     * 將一個 member 元素及其 score值加入到有序集 key 當中。
     * 如果某個 member 已經是有序集的成員,那麼更新這個 member 的 score 值,
     *並通過重新插入這個 member 元素,來保證該 member 在正確的位置上。
     * @param key
     * @param score
     * @param member
     * @return
     */
    public Long zadd(String key, double score, String member) {
        Jedis jedis = getJedis();
        Long result = jedis.zadd(key, score, member);
        releaseJedis(jedis);
        return result;
    }
    /**
     * sorted set
     * 移除有序集 key 中的一成員member,不存在的成員將被忽略。
     * @param key
     * @param member
     * @return
     */
    public Long zrem(String key, String member) {
        Jedis jedis = getJedis();
        Long result = jedis.zrem(key, member);
        releaseJedis(jedis);
        return result;
    }
    /**sorted set
     * 返回集合 key集合中元素的數量
     * @param key
     * @return
     */
    public Long zcard(String key) {
        Jedis jedis = getJedis();
        Long result = jedis.zcard(key);
        releaseJedis(jedis);
        return result;
    }
    /**
     * 返回有序集 key 中, score 值在 min 和 max 之間(預設包括 score 值等於 min 或 max )的成員的數量。
     * @param key
     * @param min
     * @param max
     * @return
     */
    public Long zcount(String key, double min, double max) {
        Jedis jedis = getJedis();
        Long result = jedis.zcount(key, min, max);
        releaseJedis(jedis);
        return result;
    }
    /**
     * 返回有序集 key 中,成員 member 的 score 值。
     * @param key
     * @param member
     * @return
     */
    public Double zscore(String key, String member) {
        Jedis jedis = getJedis();
        Double result = jedis.zscore(key, member);
        releaseJedis(jedis);
        return result;
    }
    /**
     * 為有序集 key 的成員 member 的 score 值加上增量"score"
     * @param key
     * @param score
     * @param member
     * @return
     */
    public Double zincrby(String key, double score, String member) {
        Jedis jedis = getJedis();
        Double result = jedis.zincrby(key, score, member);
        releaseJedis(jedis);
        return result;
    }
   /**
    * 返回有序集 key 中,指定區間內的成員。其中成員的位置按 score 值遞增(從小到大)來排序。
    * @param key
    * @param start
    * @param end
    * @return
    */
    public Set<String> zrange(String key, int start, int end) {
        Jedis jedis = getJedis();
        Set<String> result = jedis.zrange(key, start, end);
        releaseJedis(jedis);
        return result;
    }
    /**
     * 其中成員的位置按 score 值遞減(從大到小)來排列。
     * @param key
     * @param start
     * @param end
     * @return
     */
    public Set<String> zrevrange(String key, int start, int end) {
        Jedis jedis = getJedis();
        Set<String> result = jedis.zrevrange(key, start, end);
        releaseJedis(jedis);
        return result;
    }
    /**
     * 返回有序集 key 中, score 值介於 max 和 min 之間(預設包括等於 max 或 min )的所有的成員。
     * 有序整合員按 score 值遞減(從大到小)的次序排列。
     * @param key
     * @param max
     * @param min
     * @param offset
     * @param count
     * @return
     */
    public Set<String> zrevrangeByScore(String key, double max, double min,int offset, int count) {
        Jedis jedis=getJedis();
        try{
            Set<String> result=jedis.zrevrangeByScore(key, max, min, offset, count);
            return result;
        }finally{
            releaseJedis(jedis);
        }
    }


    public Set<String> zrevrangeByScore(String key, double max, double min) {
        Jedis jedis=getJedis();
        try{
            Set<String> result=jedis.zrevrangeByScore(key, max, min);
            return result;
        }finally{
            releaseJedis(jedis);
        }
    }
    /**
     * 返回有序集 key 中,所有 score 值介於 min 和 max 之間(包括等於 min 或 max )的成員。
     * 有序整合員按 score 值遞增(從小到大)次序排列。
     * @param key
     * @param min
     * @param max
     * @return
     */
    public Set<String> zrangeByScore(String key, double min, double max) {
        Jedis jedis=getJedis();
        try{
            Set<String> result=jedis.zrangeByScore(key, min, max);
            return result;
        }finally{
            releaseJedis(jedis);
        }
    }
    /**
     * 返回有序集 key 中成員 member 的排名。其中有序整合員按 score 值遞增(從小到大)順序排列。
     *  排名以 0 為底,也就是說, score 值最小的成員排名為 0 。
     */


    public Long zrank(String key, String member) {
        Jedis jedis = getJedis();
        Long result = jedis.zrank(key, member);
        releaseJedis(jedis);
        return result;
    }
    /**
     * 返回有序集 key 中成員 member 的排名。其中有序整合員按 score 值遞減(從大到小)排序。
     * 排名以 0 為底,也就是說, score 值最大的成員排名為 0 。
     * @param key
     * @param member
     * @return
     */
    public Long zrevrank(String key, String member) {
        Jedis jedis = getJedis();
        Long result = jedis.zrevrank(key, member);
        releaseJedis(jedis);
        return result;
    }
    /**
     * 移除有序集 key 中,指定排名(rank)區間內的所有成員。
     * @param key
     * @param start
     * @param end
     * @return
     */
    public Long zremrangeByRank(String key, int start, int end) {
        Jedis jedis = getJedis();
        Long result = jedis.zremrangeByRank(key, start, end);
        releaseJedis(jedis);
        return result;
    }
    /**
     * 移除有序集 key 中,所有 score 值介於 min 和 max 之間(包括等於 min 或 max )的成員。
     * @param key
     * @param start
     * @param end
     * @return
     */


    public Long zremrangeByScore(String key, double start, double end) {
        Jedis jedis = getJedis();
        Long result = jedis.zremrangeByScore(key, start, end);
        releaseJedis(jedis);
        return result;
    }
    /**
     * 計算給定的一個或多個有序集的交集,並將該交集(結果集)儲存到 destination 。
     * 預設情況下,結果集中某個成員的 score 值是所有給定集下該成員 score 值之和.
     * @param dstkey
     * @param sets
     * @return
     */
    public Long zinterstore(String dstkey, String... sets) {
        Jedis jedis = getJedis();
        Long result = jedis.zinterstore(dstkey, sets);
        releaseJedis(jedis);
        return result;
    }
    /**
     * 計算給定的一個或多個有序集的並集,並將該並集(結果集)儲存到 destination 。
     * 預設情況下,結果集中某個成員的 score 值是所有給定集下該成員 score 值之 和 。
     * @param dstkey
     * @param sets
     * @return
     */
    public Long zunionstore(String dstkey, String... sets) {
        Jedis jedis = getJedis();
        Long result = jedis.zunionstore(dstkey, sets);
        releaseJedis(jedis);
        return result;
    }


    /**String
     * 通過key獲取儲存在redis中的value
     * 並釋放連線
     * @param key
     * @return 成功返回value 失敗返回null
     */
    public  byte[]  get(byte[] key) {
        Jedis jedis = null;
        byte[] result = null;
        try {
            jedis = getJedis();
            result = jedis.get(key);
        } catch (Exception e) {
            releaseBrokenJedis(jedis);
            e.printStackTrace();
        } finally {
            releaseJedis(jedis);
        }
        return result;
    }


    /**string
     * 向redis存入key和value,並釋放連線資源
     * 如果key已經存在 則覆蓋
     * @param key
     * @param value
     * @return 成功 返回OK 失敗返回 0
     */
    public String set(byte[] key, byte[] value) {
        Jedis jedis = null;
        String result = null;
        try {
            jedis = getJedis();
            result = jedis.set(key, value);
        } catch (Exception e) {
            releaseBrokenJedis(jedis);
            e.printStackTrace();
            result = "0";
        } finally {
            releaseJedis(jedis);
        }
        return result;
    }


    /**
     * <p>
     * 設定key value,如果key已經存在則返回0,nx==> not exist
     * @param key
     * @param value
     * @return 成功返回1 如果存在 和 發生異常 返回 0
     */
    public Long setnx(String key, String value) {
        Jedis jedis = null;
        Long result = 0L;
        try {
            jedis = getJedis();
            result = jedis.setnx(key, value);
        } catch (Exception e) {
            releaseBrokenJedis(jedis);
            e.printStackTrace();
        } finally {
            releaseJedis(jedis);
        }


        return result;
    }
  /**string
   * 將給定 key 的值設為 value ,並返回 key 的舊值(old value)。
   * @param key
   * @param value
   * @return
   */
    public String getSet(String key, String value) {
        Jedis jedis = getJedis();
        String result = jedis.getSet(key, value);
        releaseJedis(jedis);
        return result;
    }
/**
 * 返回所有(一個或多個)給定 key 的值。
 * 如果給定的 key 裡面,有某個 key 不存在,那麼這個 key 返回特殊值 nil 。因此,該命令永不失敗。
 * @param keys
 * @return
 */
    public List<String> mget(String[] keys) {
        Jedis jedis = getJedis();
        List<String> result = jedis.mget(keys);
        releaseJedis(jedis);
        return result;
    }
   /**
    * 同時設定一個或多個 key-value 對。
    * 有會覆蓋
    * @param keysvalues
    */
    public void mset(String... keysvalues) {
        Jedis jedis = getJedis();
        jedis.mset(keysvalues);
        releaseJedis(jedis);
    }
    /**
     * key不存在時才插入
     * @param keysvalues
     */
    public void msetnx(String... keysvalues) {
        Jedis jedis = getJedis();
        jedis.msetnx(keysvalues);
        releaseJedis(jedis);
    }
     /**
      * 將 key 所儲存的值加上增量 increment 。
      * 如果 key 不存在,那麼 key 的值會先被初始化為 0 ,然後再執行 INCRBY 命令。
      * @param key
      * @param integer
      * @return
      */
    public Long incrBy(String key, Integer integer) {
        Jedis jedis = getJedis();
        Long result = jedis.incrBy(key, integer);
        releaseJedis(jedis);
        return result;
    }
    /**
     * 返回 key 所儲存的字串值的長度。
     * @param key
     * @return
     */
    public Long strlen(String key) {
        Jedis jedis = getJedis();
        Long result = jedis.strlen(key);
        releaseJedis(jedis);
        return result;
    }


    /**
     * 通過key 對value進行加值+1操作,當value不是int型別時會返回錯誤,當key不存在是則value為1
     * @param key
     * @return 加值後的結果
     */
    public Long incr(String key) {
        Jedis jedis = getJedis();
        Long result = jedis.incr(key);
        releaseJedis(jedis);
        return result;
    }






    /**
     * 對key的值做減減操作,如果key不存在,則設定key為-1


     * @param key
     * @return
     */
    public Long decr(String key) {
        Jedis jedis = getJedis();
        Long result = jedis.decr(key);
        releaseJedis(jedis);
        return result;
    }


    /**
     * 減去指定的值
     * @param key
     * @param integer
     * @return
     */
    public Long decrBy(String key, Integer integer) {
&nb