最近尝试用srping-data-redis+jedis,用线程池方式读写redis,参考别人一些方法,遇到一些问题,一一解决。
如果有遇到类似问题,可能需关注下版本,本人验证的srping-data-redis+jedis版本2.4.2,jedis版本3.5.2。
<dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> <version>2.8.6</version> </dependency> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>3.5.2</version> </dependency> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-redis</artifactId> <version>2.4.2</version> </dependency>
贴上代码,实现部分接口功能,可以基于下面代码继续新增接口,本地单机redis和线上redis集群均测试过,需注意标红代码。
package com.livelink.data.config; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.connection.jedis.JedisConnectionFactory; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.data.redis.serializer.StringRedisSerializer; import redis.clients.jedis.JedisPoolConfig; @Configuration @EnableAutoConfiguration public class RedisConfig { private static Logger logger = LoggerFactory.getLogger(RedisConfig.class); @Value("${redis.host}") private String redisHost; @Value("${redis.port}") private int redisPort; @Value("${redis.timeout}") private int redisTimeout; @Value("${redis.password}") private String passWord; @Value("${redis.database}") private int redisDb; @Value("${redis.pool.max-active}") private int maxActive; @Value("${redis.pool.max-wait}") private int maxWait; @Value("${redis.pool.max-idle}") private int maxIdle; @Value("${redis.pool.min-idle}") private int minIdle; @Bean // @ConfigurationProperties(prefix = "redis") // should not do this, that will make you in trouble public JedisPoolConfig getJedisPoolConfig() { JedisPoolConfig jedisPoolConfig = new JedisPoolConfig(); jedisPoolConfig.setMaxTotal(maxActive); jedisPoolConfig.setMaxIdle(maxIdle); jedisPoolConfig.setMaxWaitMillis(maxWait); jedisPoolConfig.setMinIdle(minIdle); return jedisPoolConfig; } @Bean public JedisConnectionFactory getConnectionFactory() { JedisConnectionFactory factory = new JedisConnectionFactory(); factory.setUsePool(true); factory.setPoolConfig(getJedisPoolConfig()); factory.setHostName(redisHost); factory.setPassword(passWord); factory.setPort(redisPort); factory.setDatabase(redisDb); return factory; } @Bean public RedisTemplate<?, ?> getRedisTemplate() { JedisConnectionFactory factory = getConnectionFactory(); RedisTemplate<?, ?> template = new StringRedisTemplate(factory); template.setKeySerializer(new StringRedisSerializer()); return template; } }
定义redis接口
package com.livelink.data.service; import java.util.List; public interface RedisService { String get(String key); boolean set(String key, String value); boolean expire(String key, long expire); long del(final String key); <T> boolean setList(String key, List<T> list); <T> List<T> getList(String key, Class<T> clz); long lpush(String key, Object obj); long rpush(String key, Object obj); String lpop(String key); Long incr(final String key); Long incrEx(final String key, int seconds); }
实现redis接口
package com.livelink.data.service.impl; import com.google.gson.Gson; import com.google.gson.reflect.TypeToken; import com.livelink.data.service.RedisService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.dao.DataAccessException; import org.springframework.data.redis.connection.RedisConnection; import org.springframework.data.redis.core.RedisCallback; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.serializer.RedisSerializer; import org.springframework.stereotype.Service; import javax.annotation.Resource; import java.util.List; import java.util.concurrent.TimeUnit; @Service public class RedisServiceImpl implements RedisService { private static Logger logger = LoggerFactory.getLogger(RedisServiceImpl.class); @Resource private RedisTemplate<String, ?> redisTemplate; private static Gson gson = new Gson(); @Override public boolean set(final String key, final String value) { boolean result = redisTemplate.execute(new RedisCallback<Boolean>() { @Override public Boolean doInRedis(RedisConnection connection) throws DataAccessException { RedisSerializer<String> serializer = redisTemplate.getStringSerializer(); connection.set(serializer.serialize(key), serializer.serialize(value)); return true; } }); return result; } @Override public String get(final String key){ String result = redisTemplate.execute(new RedisCallback<String>() { @Override public String doInRedis(RedisConnection connection) throws DataAccessException { RedisSerializer<String> serializer = redisTemplate.getStringSerializer(); byte[] value = connection.get(serializer.serialize(key)); return serializer.deserialize(value); } }); return result; } @Override public long del(final String key){ long result = redisTemplate.execute(new RedisCallback<Long>() { @Override public Long doInRedis(RedisConnection connection) throws DataAccessException { RedisSerializer<String> serializer = redisTemplate.getStringSerializer(); long value = connection.del(serializer.serialize(key)); return value; } }); return result; } @Override public boolean expire(final String key, long expire) { return redisTemplate.expire(key, expire, TimeUnit.SECONDS); } @Override public <T> boolean setList(String key, List<T> list) { String value = gson.toJson(list); return set(key,value); } @Override public <T> List<T> getList(String key,Class<T> clz) { String json = get(key); if(json!=null){ List<T> list = gson.fromJson(json, new TypeToken<List<T>>() {}.getType()); return list; } return null; } @Override public long lpush(final String key, Object obj) { final String value = gson.toJson(obj); long result = redisTemplate.execute(new RedisCallback<Long>() { @Override public Long doInRedis(RedisConnection connection) throws DataAccessException { RedisSerializer<String> serializer = redisTemplate.getStringSerializer(); long count = connection.lPush(serializer.serialize(key), serializer.serialize(value)); return count; } }); return result; } @Override public long rpush(final String key, Object obj) { final String value = gson.toJson(obj); long result = redisTemplate.execute(new RedisCallback<Long>() { @Override public Long doInRedis(RedisConnection connection) throws DataAccessException { RedisSerializer<String> serializer = redisTemplate.getStringSerializer(); long count = connection.rPush(serializer.serialize(key), serializer.serialize(value)); return count; } }); return result; } @Override public String lpop(final String key) { String result = redisTemplate.execute(new RedisCallback<String>() { @Override public String doInRedis(RedisConnection connection) throws DataAccessException { RedisSerializer<String> serializer = redisTemplate.getStringSerializer(); byte[] res = connection.lPop(serializer.serialize(key)); return serializer.deserialize(res); } }); return result; } @Override public Long incr(String key) { Long result = redisTemplate.execute(new RedisCallback<Long>() { @Override public Long doInRedis(RedisConnection connection) throws DataAccessException { RedisSerializer<String> serializer = redisTemplate.getStringSerializer(); return connection.incr(serializer.serialize(key)); } }); return result; } @Override public Long incrEx(String key, int seconds) { Long result = redisTemplate.execute(new RedisCallback<Long>() { @Override public Long doInRedis(RedisConnection connection) throws DataAccessException { RedisSerializer<String> serializer = redisTemplate.getStringSerializer(); Long res = connection.incr(serializer.serialize(key)); if (res.equals(1L)) { if (connection.expire(serializer.serialize(key), seconds)) { logger.info("connection.expire succ"); } } else { logger.info("not equal"); } return res; } }); return result; } }
线上集群模式下不支持指定database,否则可能报错如下:
Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.data.redis.RedisConnectionFailureException: Cannot get Jedis connection; nested exception is redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the pool] with root cause
redis.clients.jedis.exceptions.JedisDataException: only db 0 support in cluster mode
idea提示Deprecated代码:
看提示已经不建议使用这些方法,暂时先用着。
如有好的建议和代码示例,欢迎指点~