http://blog.csdn.net/yerenyuan_pku/article/details/72863323

我们知道Jedis在处理Redis的单机版和集群版时是完全不同的,有可能在开发的时候使用的是单机版,但是当项目上线后使用的则是集群版,这就需要能够方便的在单机版和集群版之间进行切换。我们的做法便是定义一个JedisClient接口,然后新建两个实现类来分别处理单机版和集群版,最后在spring容器中进行配置管理即可。 
首先在taotao-content-service工程下新建一个包com.taotao.content.jedis,并在该包下新建一个JedisClient接口,如下图所示。 

JedisClient接口的代码如下:

public interface JedisClient {

    String set(String key, String value);
String get(String key);
Boolean exists(String key);
Long expire(String key, int seconds);
Long ttl(String key);
Long incr(String key);
Long hset(String key, String field, String value);
String hget(String key, String field);
Long hdel(String key, String... field);
}
  • 1

接着我们再在com.taotao.content.jedis包下新建两个JedisClient的实现类,分别是单机版实现类JedisClientPool和集群版实现类JedisClientCluster。单机版实现类的代码如下:

public class JedisClientPool implements JedisClient {

    @Autowired
private JedisPool jedisPool; @Override
public String set(String key, String value) {
Jedis jedis = jedisPool.getResource();
String result = jedis.set(key, value);
jedis.close();
return result;
} @Override
public String get(String key) {
Jedis jedis = jedisPool.getResource();
String result = jedis.get(key);
jedis.close();
return result;
} @Override
public Boolean exists(String key) {
Jedis jedis = jedisPool.getResource();
Boolean result = jedis.exists(key);
jedis.close();
return result;
} @Override
public Long expire(String key, int seconds) {
Jedis jedis = jedisPool.getResource();
Long result = jedis.expire(key, seconds);
jedis.close();
return result;
} @Override
public Long ttl(String key) {
Jedis jedis = jedisPool.getResource();
Long result = jedis.ttl(key);
jedis.close();
return result;
} @Override
public Long incr(String key) {
Jedis jedis = jedisPool.getResource();
Long result = jedis.incr(key);
jedis.close();
return result;
} @Override
public Long hset(String key, String field, String value) {
Jedis jedis = jedisPool.getResource();
Long result = jedis.hset(key, field, value);
jedis.close();
return result;
} @Override
public String hget(String key, String field) {
Jedis jedis = jedisPool.getResource();
String result = jedis.hget(key, field);
jedis.close();
return result;
} @Override
public Long hdel(String key, String... field) {
Jedis jedis = jedisPool.getResource();
Long result = jedis.hdel(key, field);
jedis.close();
return result;
} }
  • 1

集群版实现类的代码如下:

public class JedisClientCluster implements JedisClient {

    @Autowired
private JedisCluster jedisCluster; @Override
public String set(String key, String value) {
return jedisCluster.set(key, value);
} @Override
public String get(String key) {
return jedisCluster.get(key);
} @Override
public Boolean exists(String key) {
return jedisCluster.exists(key);
} @Override
public Long expire(String key, int seconds) {
return jedisCluster.expire(key, seconds);
} @Override
public Long ttl(String key) {
return jedisCluster.ttl(key);
} @Override
public Long incr(String key) {
return jedisCluster.incr(key);
} @Override
public Long hset(String key, String field, String value) {
return jedisCluster.hset(key, field, value);
} @Override
public String hget(String key, String field) {
return jedisCluster.hget(key, field);
} @Override
public Long hdel(String key, String... field) {
return jedisCluster.hdel(key, field);
} }
  • 1

我们先来测试单机版如何使用,我们在单机版实现类JedisClientPool当中可以看到使用注入的方式注入JedisPool,要注入,Spring容器当中便要管理这个Bean,因此我们在taotao-content-service工程的src/main/resources/spring目录下新建一个applicationContext-redis.xml配置文件来专门管理Jedis客户端的使用,内容如下:

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.2.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.2.xsd"> <!-- 开启注解 -->
<context:annotation-config /> <!-- redis单机版 -->
<bean id="jedisPool" class="redis.clients.jedis.JedisPool">
<constructor-arg name="host" value="192.168.25.128" />
<constructor-arg name="port" value="6379" />
</bean>
<bean id="jedisClientPool" class="com.taotao.content.jedis.JedisClientPool"></bean> </beans>
  • 1

注意:上面的配置文件中关于开启注解的配置是为了单元测试类中的测试代码而添加的,因为使用单元测试类测试的话,不会加载其它配置文件,相应地就不会开启注解,所以需要这句配置,测试完后记得要删掉这个配置哟! 
针对applicationContext-redis.xml配置文件的内容有一点需要说明一下,我们看看下图,applicationContext-service.xml文件配置的扫描包的范围是com.taotao.content.service,那么如果我们不指定要扫描com.taotao.content.jedis包的话,能不能把JedisPool注入进来呢?答案是可以的,因为下图中<context:component-scan base-package="com.taotao.content.service"></context:component-scan>这句配置不仅指定了一个包扫描范围,还有一个功能就是开启注解(也就是同时具备两个功能),开启注解后写到Spring容器中的Bean都可以被外界成功注入。 

下面我们在JedisTest单元测试类中新建一个testJedisClientPool单元测试方法进行测试,发现Redis单机版没有任何问题,如下图所示。 

测试完了Redis单机版,现在我们来测试Redis集群版,在配置文件中注释掉单机版配置,添加集群版配置,如下所示。

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.2.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.2.xsd"> <!-- 开启注解 -->
<context:annotation-config /> <!-- redis单机版 -->
<!-- <bean id="jedisPool" class="redis.clients.jedis.JedisPool">
<constructor-arg name="host" value="192.168.25.128" />
<constructor-arg name="port" value="6379" />
</bean>
<bean id="jedisClientPool" class="com.taotao.content.jedis.JedisClientPool"></bean> -->
<!-- 集群版,注意:单机版和集群版不能共存!!! -->
<bean id="jedisCluster" class="redis.clients.jedis.JedisCluster">
<constructor-arg name="nodes">
<set>
<bean class="redis.clients.jedis.HostAndPort">
<constructor-arg name="host" value="192.168.25.128" />
<constructor-arg name="port" value="7001" />
</bean>
<bean class="redis.clients.jedis.HostAndPort">
<constructor-arg name="host" value="192.168.25.128" />
<constructor-arg name="port" value="7002" />
</bean>
<bean class="redis.clients.jedis.HostAndPort">
<constructor-arg name="host" value="192.168.25.128" />
<constructor-arg name="port" value="7003" />
</bean>
<bean class="redis.clients.jedis.HostAndPort">
<constructor-arg name="host" value="192.168.25.128" />
<constructor-arg name="port" value="7004" />
</bean>
<bean class="redis.clients.jedis.HostAndPort">
<constructor-arg name="host" value="192.168.25.128" />
<constructor-arg name="port" value="7005" />
</bean>
<bean class="redis.clients.jedis.HostAndPort">
<constructor-arg name="host" value="192.168.25.128" />
<constructor-arg name="port" value="7006" />
</bean>
</set>
</constructor-arg>
</bean>
<bean id="jedisClientCluster" class="com.taotao.content.jedis.JedisClientCluster"></bean>
</beans>

注意:单机版和集群版不能共存,使用单机版时注释集群版的配置,使用集群版,把单机版注释。 
添加完集群版配置后,我们的测试方法不用做任何修改,再运行一下,如下图所示,运行一切正常。 

我们再到Redis集群中的任何一个节点去检查一下,比如我在192.168.25.128:7006这个节点上使用客户端连接集群,使用命令get client来获取它的值,发现client被保存到了槽号为3847的上面,该槽号在 192.168.25.128:7001节点上,如下图所示,说明client确实保存到集群当中了。 

这样,以后我们只需修改Spring配置文件便可轻松在单机版和集群版之间进行切换。最后记得把applicationContext-redis.xml文件中用于测试的开启注解的配置<context:annotation-config/>去掉,因为在applicationContext-service.xml文件中已经开启过注解了,系统运行会把所有的配置文件都加载进来,因此只需一处开启注解就可以了。 
至此,用Spring容器来管理单机版和集群版Redis实现类便学习完了。

(转)淘淘商城系列——使用Spring来管理Redis单机版和集群版的更多相关文章

  1. Redis系列(二):Redis高可用集群

    一.集群模式 Redis集群是一个由多个主从节点组成的高可用集群,它具有复制.高可用和分片等特性 二.集群部署 1.环境 3台主机分别是: 192.168.160.146 192.168.160.15 ...

  2. Spring集成jedis支持Redis3.0集群

    接着上一节,我们通过spring FactoryBean实现redis 3.0集群JedisCluster与spring集成.  http://www.linuxidc.com/Linux/2016- ...

  3. spring cloud系列教程第六篇-Eureka集群版

    spring cloud系列教程第六篇-Eureka集群版 本文主要内容: 本文来源:本文由凯哥Java(kaigejava)发布在博客园博客的.转载请注明 1:Eureka执行步骤理解 2:集群原理 ...

  4. 使用Spring Data Redis操作Redis(集群版)

    说明:请注意Spring Data Redis的版本以及Spring的版本!最新版本的Spring Data Redis已经去除Jedis的依赖包,需要自行引入,这个是个坑点.并且会与一些低版本的Sp ...

  5. JAVAEE——宜立方商城08:Zookeeper+SolrCloud集群搭建、搜索功能切换到集群版、Activemq消息队列搭建与使用

    1. 学习计划 1.solr集群搭建 2.使用solrj管理solr集群 3.把搜索功能切换到集群版 4.添加商品同步索引库. a) Activemq b) 发送消息 c) 接收消息 2. 什么是So ...

  6. spring Cloud服务注册中心Eureka集群

    spring Cloud服务注册中心Eureka集群配置: 在application.yml文件加以下配置: server: port: 8761 tomcat: uri-encoding: UTF- ...

  7. 【Spring Cloud笔记】 Eureka通过集群实现高可用

    Eureka实现服务注册与发现,在Spring Cloud微服务中起着关键性的作用,必须保障其高可用,常规方案无非通过集群实现.这里在本地机器搭建一个伪集群环境,通过两个节点实现相互注册,并通过主备数 ...

  8. Kubernetes(k8s)集群部署(k8s企业级Docker容器集群管理)系列之自签TLS证书及Etcd集群部署(二)

    0.前言 整体架构目录:ASP.NET Core分布式项目实战-目录 k8s架构目录:Kubernetes(k8s)集群部署(k8s企业级Docker容器集群管理)系列目录 一.服务器设置 1.把每一 ...

  9. Spring Boot + Redis 实现Shiro集群

    为实现Web应用的分布式集群部署,要解决登录session的统一.本文利用shiro做权限控制,redis做session存储,结合spring boot快速配置实现session共享. 1.引入相关 ...

随机推荐

  1. openstack页面自己定义插件使用具体解释(django、ajax、post)(zTree为例)

    感谢朋友支持本博客,欢迎共同探讨交流.因为能力和时间有限,错误之处在所难免,欢迎指正! 如有转载.请保留源作者博客信息. Better Me的博客:blog.csdn.net/tantexian 如需 ...

  2. 状压DP问题

    状态压缩·一 题目传送:#1044 : 状态压缩·一 AC代码: #include <map> #include <set> #include <list> #in ...

  3. 划分问题(dp)

    给出一个整数集合  , 将这个集合分成2个 和相等的集合. 思路就是  总和的一半作为一个目标容量,在集合中寻找能否够有元素的和恰好为这个目标容量,也就转化为一个类似01背包问题. 这篇文章讲的比較具 ...

  4. 2016/1/14 java随机数生成

    1.Math库里的static(静态)方法random() 该方法的作用是产生0到1之间(包括0,但不包括1)的一个double值. double rand = Math.random(); 2.通过 ...

  5. ZOJ Design the city LCA转RMQ

    Design the city Time Limit: 1 Second      Memory Limit: 32768 KB Cerror is the mayor of city HangZho ...

  6. Python读取大文件(GB)

    Python读取大文件(GB) - CSDN博客 https://blog.csdn.net/shudaqi2010/article/details/54017766

  7. linux 点命令

    cat a date . a Mon Jun :: CST linux .(点命令):读取并且在当前的shell中执行文件中的命令

  8. HDU 1724 Ellipse 【自适应Simpson积分】

    Ellipse Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Sub ...

  9. android压力测试命令monkey详解【转】

    本文转载自:http://www.jb51.net/article/48557.htm 作者: 字体:[增加 减小] 类型:转载 时间:2014-03-29我要评论 这篇文章主要介绍了android ...

  10. mipi差分信号原理

    差分信号,什么是差分信号 一个差分信号是用一个数值来表示两个物理量之间的差异.从严格意义上来讲,所有电压信号都是差分的,因为一个电压只能是相对于另一个电压而言的.在某些系统里,系统’地’被用作电压基准 ...