Redis整合Spring及Jedis客户端的使用
一、整合
1、首先导入整合的jar包
注意:jdies和commons-pool两个jar的版本是有对应关系的,注意引入jar包是要配对使用,否则将会报错。因为commons-pooljar的目录根据版本的变化,目录结构会变。前面的版本是org.apache.pool,而后面的版本是org.apache.pool2...
redis是一个key-value存储系统。和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)、zset(sorted set --有序集合)和hash(哈希类型)。这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。在此基础上,redis支持各种不同方式的排序。与memcached一样,为了保证效率,数据都是缓存在内存中。区别的是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了master-slave(主从)
2、编写Redis.properties
# redis normal group # \u4fdd\u6301\u7684\u6700\u5927\u6d3b\u8dc3\u8fde\u63a5\u6570 redis.maxActive=1000 # \u6700\u5927\u7684\u7a7a\u95f2\u8fde\u63a5\u6570 redis.maxIdle=500 # \u6700\u5927\u7684\u7b49\u5f85\u8fde\u63a5\u6570 redis.maxWait=2000 # \u6700\u5c0f\u7684\u7a7a\u95f2\u8fde\u63a5\u6570 redis.minIdle=3 # \u8fde\u63a5\u7528\u5b8c\u65f6\u7684\u52a8\u4f5c\uff0c0 \u5931\u8d25\uff0c1 \u963b\u585e\uff0c2 \u589e\u957f redis.whenExhaustedAction=1 #redis.host.1=111.204.247.2 redis.host=10.199.222.122 #redis.host.1=10.199.10.56 redis.port=6379 redis.db.share=0 redis.password=admin redis.timeout=15000 redis.usePool=true
3、spring-redis.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"> <beans default-lazy-init="false"> <bean id="redisPoolConfig" class="redis.clients.jedis.JedisPoolConfig" singleton="true"> <!-- 保持的最大活跃连接数 --> <property name="maxActive" value="${redis.maxActive}" /> <!-- 最大的空闲连接数 --> <property name="maxIdle" value="${redis.maxIdle}" /> <!-- 最大的等待连接数 --> <property name="maxWait" value="${redis.maxWait}" /> <!-- 最小的空闲连接数 --> <property name="minIdle" value="${redis.minIdle}" /> <!-- 是否开启建立时验证,如果验证失败,将不加入队列 --> <property name="testOnBorrow" value="true" /> <!-- 是否开启放回队列时验证,如果验证失败,将不加入队列 --> <property name="testOnReturn" value="true" /> <!-- 是否开启等待状态转换到活动状态时验证,如果验证失败,将不加入队列 --> <property name="testWhileIdle" value="true" /> <!-- 连接用完时的动作,0 失败,1 阻塞,2 增长 --> <!-- <property name="whenExhaustedAction" value="${redis.whenExhaustedAction}" /> --> </bean> <bean name="jedisPool" id="jedisPool" class="redis.clients.jedis.JedisPool" singleton="true"> <constructor-arg> <ref bean="redisPoolConfig" /> </constructor-arg> <constructor-arg> <value>${redis.host}</value> </constructor-arg> <constructor-arg> <value>${redis.port}</value> </constructor-arg> <constructor-arg> <value>4000</value> </constructor-arg> <constructor-arg> <value>${redis.password}</value> </constructor-arg> </bean> <bean <!-- 引入 JedisClient客户端--> id="redisClient"class="com.crs.ticket.utils.cache.JedisClient" singleton="true"> <property name="pool" ref="jedisPool" /> <property name="db" value="${redis.db.share}" /> </bean> <bean <!-- 引入 redisUtil工具类--> id="redisUtil" class="com.crs.ticket.utils.cache.RedisUtil" singleton="true"> <property name="jedisClient" ref="redisClient" /> </bean> </beans>
4.在spring-config配置文件中添加下边引用
<import resource="spring-redis.xml" />
5.web.xml添加启动加载spring容器
<!-- spring 容器 --> <context-param> <param-name>contextConfigLocation</param-name> <param-value> classpath:config/spring-config.xml </param-value> </context-param>
6.编写redisUtil
package com.crs.ticket.utils.cache; import java.io.Serializable; import java.util.ArrayList; import java.util.Date; import java.util.List; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import redis.clients.jedis.Jedis; /** * 先进先出 redis 队列 * @author lichao * * @param <T> */ public class RedisUtil { private static Log logger = LogFactory.getLog(JedisClient.class); protected JedisClient jedisClient; public RedisUtil() { } public void push(String key,Object t) { Jedis redis = null; try { redis = jedisClient.getJedis(); redis.rpush(JedisClient.w(key), JedisClient.w((Serializable) t)); jedisClient.returnResource(redis); } catch (Exception e) { e.printStackTrace(); if(redis != null) jedisClient.returnBrokenResource(redis); } } public Object pop(String key) { Jedis redis = null; try { redis = jedisClient.getJedis(); List<byte[]> lpop = redis.blpop(30, JedisClient.w(key)); jedisClient.returnResource(redis); Object object = null; if (lpop != null && lpop.size() > 1) { object = JedisClient.u(lpop.get(1)); } return object; } catch (Exception e) { e.printStackTrace(); if(redis != null) jedisClient.returnBrokenResource(redis); } return null; } public void pushList(String key,Integer num) { try { for (int i = 0; i < num; i++) { push(key, new CacheModel()); // jedisCluster.rpush(SerializeUtil.w(key), SerializeUtil.w((Serializable) new CacheModel())); } } catch (Exception e) { e.printStackTrace(); } logger.info("添加后redisKeyTemp:"+key+",剩余数量:"+ llen(key)); } public List<Object> popList(String key,Integer num) throws Exception { logger.info("开始"+new Date().toString()); Long llen = llen(key); if( llen < num){ throw new Exception("库存不足"); } List<Object> list = new ArrayList<Object>(); for (int i = 0; i < num; i++) { Object lpop = pop(key); if (lpop != null) { list.add(lpop); }else{ pushList(key,list.size()); throw new Exception("库存不足"); } } logger.info("扣除后redisKey:"+key+",剩余数量:"+llen(key)); logger.info("结束"+new Date().toString()); return list; } public Long llen(String key){ Jedis redis = null; try { logger.info("开始"+new Date().toString()); redis = jedisClient.getJedis(); Long llen = redis.llen(SerializeUtil.w(key)); logger.info("结束"+new Date().toString()); jedisClient.returnResource(redis); return llen; } catch (Exception e) { e.printStackTrace(); } return null; } /** * 设置 list * @param <T> * @param key * @param value * @param expire */ public <T> void setList(String key ,List<T> list ,int expire){ Jedis redis = null; try { redis = jedisClient.getJedis(); redis.set(key.getBytes(),SerializeUtil.w((Serializable)list)); redis.expire(key, expire); } catch (Exception e) { logger.error("Set key error : "+e); } finally{ if(redis!=null){ jedisClient.returnBrokenResource(redis); } } } /** * 设置 list * @param <T> * @param key * @param value */ public <T> void setList(String key ,List<T> list){ Jedis redis = null; try { redis = jedisClient.getJedis(); redis.set(key.getBytes(),SerializeUtil.w((Serializable)list)); } catch (Exception e) { logger.error("Set key error : "+e); } finally{ if(redis!=null){ jedisClient.returnBrokenResource(redis); } } } /** * 获取list * @param <T> * @param key * @return list */ @SuppressWarnings("unchecked") public <T> List<T> getList(String key){ Jedis redis = null; try { redis = jedisClient.getJedis(); if(redis == null || !redis.exists(key.getBytes())){ return null; } byte[] in = redis.get(key.getBytes()); List<T> list = (List<T>) SerializeUtil.u(in); return list; } catch (Exception e) { e.printStackTrace(); }finally{ if(redis!=null){ jedisClient.returnBrokenResource(redis); } } return null; } public JedisClient getJedisClient() { return jedisClient; } public void setJedisClient(JedisClient jedisClient) { this.jedisClient = jedisClient; } }
7、编写JedisClient
package com.crs.ticket.utils.cache; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; import java.util.List; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import redis.clients.jedis.Jedis; import redis.clients.jedis.JedisPool; import redis.clients.jedis.JedisPoolConfig; public class JedisClient{ private static Log logger = LogFactory.getLog(JedisClient.class); private JedisPool pool; private Integer db = 0; /** * 获取Jedis对象 * @return */ public Jedis getJedis() { Jedis jedis = pool.getResource(); jedis.select(db); return jedis; } /** * 放回Jedis对象 * @param jedis */ public void returnResource(Jedis jedis) { pool.returnResource(jedis); } public void returnBrokenResource(Jedis jedis) { pool.returnBrokenResource(jedis); } public void setPool(JedisPool pool) { this.pool = pool; } public void setDb(Integer db) { this.db = db; } public static byte[] w(Serializable o) { try { if (o instanceof String) { String str = (String) o; return str.getBytes(); } else { ByteArrayOutputStream stream = new ByteArrayOutputStream(); ObjectOutputStream s = new ObjectOutputStream(stream); s.writeObject(o); s.flush(); s.close(); return stream.toByteArray(); } } catch (IOException e) { e.printStackTrace(); } return null; } @SuppressWarnings("unchecked") public static <T> T u(byte[] bytes) { try { InputStream in = new ByteArrayInputStream(bytes); ObjectInputStream is = new ObjectInputStream(in); return (T) is.readObject(); } catch (IOException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } return null; } public static <T> void main(String[] args) throws IOException, ClassNotFoundException { }
8、测试
在controller文件中进行测试 @Resource RedisUtil _redisUtil; Map<String,Object> urlMap = _redisUtil.getMap("SpeUrlProdInfo:"+idSpecialUrl); if (urlMap == null) { urlMap = commonmapper.findUrlInfoByURLId(param); _redisUtil.setMap("SpeUrlProdInfo:"+idSpecialUrl, urlMap, 30*60); }
划船不用桨、杨帆不等风、一生全靠浪