一、redis-sentinel HA架构搭建
详细的搭建过程,请参考另一篇文章,地址如下:
点击打开链接
二、引入依赖的jar包
<dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>2.6.2</version> </dependency>三、Spring配置文件
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:p="http://www.springframework.org/schema/p" xmlns:cache="http://www.springframework.org/schema/cache" xmlns:jpa="http://www.springframework.org/schema/data/jpa" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache-3.1.xsd http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd"> <!-- 扫描注解包 --> <context:annotation-config /> <context:component-scan base-package="com.chhliu.redis"></context:component-scan> <!-- 加载properties文件 --> <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="locations"> <list> <value>classpath:redis.properties</value> </list> </property> </bean> <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig"> <property name="maxTotal" value="${redis.maxTotal}"></property> </bean> <!-- 配置sentinel哨兵 --> <bean id="redisSentinel" class="redis.clients.jedis.JedisSentinelPool"> <constructor-arg index="0" value="mymaster" /> <constructor-arg index="1"> <set> <value>${redis.sentinel.host1}:${redis.sentinel.port1}</value> <value>${redis.sentinel.host2}:${redis.sentinel.port2}</value> <value>${redis.sentinel.host3}:${redis.sentinel.port3}</value> </set> </constructor-arg> <constructor-arg index="2" ref="jedisPoolConfig" /> </bean> </beans>四、redis.properties配置文件
redis.maxTotal=100 redis.sentinel.host1=127.0.0.1 redis.sentinel.host2=127.0.0.1 redis.sentinel.host3=127.0.0.1 redis.sentinel.port1=26379 redis.sentinel.port2=26479 redis.sentinel.port3=26579五、定义接口服务
定义回调接口
/** * 描述:redis连接的回调接口 */ public interface ConnectionCallback<T, P> { /** * Details:连接redis服务 * @param shardedJedis jedis分片 * @return * T */ T doInConnection(P p) throws RedisOperationException; }定义接口提供的方法 public interface RedisOperations { /** * Details:执行回调服务 */ <T> T execute(ConnectionCallback<T, Jedis> action) throws RedisOperationException; /** * Details:设置key-value */ String set(final String key, final String value) throws RedisOperationException; /** * Details:设置键值对,并设置该键的过期时间 */ String set(final String key, final String value, final int expireTime) throws RedisOperationException; /** * Details:获取指定键对应的值 */ String get(final String key) throws RedisOperationException; /** * Details:删除指定的键 */ Long del(final String key) throws RedisOperationException; /** * Details:获取key值的集合 */ Set<String> keys(final String keyPattern) throws RedisOperationException; /** * Details:判断当前key是否存在 */ boolean exist(final String key) throws RedisOperationException; /** * attention:list分页操作 */ List<String> lrange(final String key, final long start, final long end) throws RedisOperationException; /** * Details:列表添加元素 */ long rpush(final String key, final String... values) throws RedisOperationException; }六、服务封装
@Service("redisTemplate") public class RedisTemplate implements RedisOperations { @Resource(name = "redisSentinel") private JedisSentinelPool jedisSentinelPool; @Override public <T> T execute(ConnectionCallback<T, Jedis> action) throws RedisOperationException { Jedis jedis = null; try { // 从连接池中获取jedis的sentinel资源 jedis = jedisSentinelPool.getResource(); // 执行回调方法 return action.doInConnection(jedis); } catch (Exception e) { throw new RedisOperationException(e, "Redis Service Failed!"); } finally { if (null != jedis) { jedis.close(); } } } @Override public boolean exist(final String key) throws RedisOperationException { return execute(new ConnectionCallback<Boolean, Jedis>() { @Override public Boolean doInConnection(Jedis jedis) throws RedisOperationException { return jedis.exists(key); } }); } @Override public String set(final String key, final String value) throws RedisOperationException { return execute(new ConnectionCallback<String, Jedis>() { @Override public String doInConnection(Jedis jedis) throws RedisOperationException { try{ return jedis.set(key, value); }catch(Exception e){ throw new RedisOperationException(e, "write to redis failed!key:" + key + " value:" + value); } } }); } @Override public String set(final String key, final String value, final int expireTime) throws RedisOperationException { return execute(new ConnectionCallback<String, Jedis>() { @Override public String doInConnection(Jedis jedis) throws RedisOperationException { try { String result = jedis.set(key, value); jedis.expire(key, expireTime); return result; } catch (Exception e) { throw new RedisOperationException(e, "write to redis failed!key:" + key + " value:" + value); } } }); } @Override public String get(final String key) throws RedisOperationException { return execute(new ConnectionCallback<String, Jedis>() { @Override public String doInConnection(Jedis jedis) throws RedisOperationException { boolean isExist = exist(key); if(isExist){ return jedis.get(key); } return null; } }); } @Override public Long del(final String key) throws RedisOperationException { return execute(new ConnectionCallback<Long, Jedis>() { @Override public Long doInConnection(Jedis jedis) throws RedisOperationException { boolean isExist = exist(key); if(isExist){ return jedis.del(key); } return null; } }); } @Override public Set<String> keys(final String keyPattern) throws RedisOperationException { return execute(new ConnectionCallback<Set<String>, Jedis>() { @Override public Set<String> doInConnection(Jedis jedis) { Set<String> sets = jedis.keys(keyPattern); return sets; } }); } @Override public List<String> lrange(final String key, final long start, final long end) throws RedisOperationException { return execute(new ConnectionCallback<List<String>, Jedis>() { @Override public List<String> doInConnection(Jedis jedis) throws RedisOperationException { return jedis.lrange(key, start, end); } }); } @Override public long rpush(final String key, final String... values) throws RedisOperationException { return execute(new ConnectionCallback<Long, Jedis>() { @Override public Long doInConnection(Jedis jedis) throws RedisOperationException { return jedis.rpush(key, values); } }); } }如果项目中需要用到其他的方法,直接用上面的callback机制添加对应的方法即可,当然,如果觉得自己封装方法比较麻烦,也可以直接使用spring data redis,这个更全面,如果我们项目中只会使用到一小部分方法,还是建议自己封装。
七、服务测试
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = { "classpath:applicationContext-redis.xml" }) public class RedisTemplateTest { @Resource(name = "redisTemplate") private RedisTemplate redisTemplate; @Test public void testSet(){ try { redisTemplate.set("1234567", "7890", 100); } catch (RedisOperationException e) { System.out.println(e.getMessage()); } } @Test public void testGet(){ try { System.out.println(redisTemplate.get("1234567")); } catch (RedisOperationException e) { System.out.println(e.getMessage()); } } }