ssm+redis伪集群(哨兵模式)

   项目用到redis做缓存。碰到了一些相关好的文章,分享给大家:

1、Redis伪集群

正确的说,哨兵模式是一主多从的结构,并不属于真正的集群,真正的集群应该是多主多从的结构,需要有多台不同物理地址的主机

本事例用一台机器搭建伪集群。 

首先需要有一台监控服务器,也就是Sentinel,一台主服务器Master,多台从服务器Slave,具体的配置可以参考另一篇博文《Redis序列之Sentinel》,假设Sentinel,Master,Slave都已经配置好了,对应地址分别为: 


Sentinel 127.0.0.1:26379,127.0.0.1:26479 
Master 127.0.0.1:10003 
Slave 127.0.0.1:10001,127.0.0.1:10002

 

2、java端配置

1)Maven的pom.xml文件中,增加redis的引用

<!--如果用1.7.5的版本,启动会有问题因此使用1.5.2的版本--> 

<dependency> 

<groupId>org.springframework.data</groupId> <artifactId>spring-data-redis</artifactId> <version>1.5.2.RELEASE</version> 

</dependency> 

<dependency> 

<groupId>redis.clients</groupId> 

<artifactId>jedis</artifactId> 

<version>2.9.0</version> 

</dependency>

2)增加redis.properties文件,文件中只需要指定sentinel即可(原来一直误认为是配置master和slave),文件内容如下

redis.sentinel.host1=127.0.0.1 

redis.sentinel.port1=26379 

redis.sentinel.host2=127.0.0.1 

redis.sentinel.port2=26479 

redis.pool.maxTotal=1024 

redis.pool.maxIdle=200 

redis.pool.maxWaitMillis=1000 

redis.pool.testOnBorrow=true redis.pool.timeBetweenEvictionRunsMillis=30000 redis.pool.minEvictableIdleTimeMillis=30000 redis.pool.softMinEvictableIdleTimeMillis=10000 redis.pool.numTestsPerEvictionRun=1024 

#1000*60*60*1 

redis.pool.expire=3600000 

redis.pool.unlock=false

3)Spring的applicationContext.xml文件中,增加Redis的配置

<!-- 引用redis属性文件 --> 

<bean 	class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> 

<property name="locations"> 

<list> <value>classpath:config/redis.properties</value> </list> 

</property> 

</bean>

<!-- 启动缓存注解功能,否则缓解不会生效 --> 

<cache:annotation-driven cache-manager="cacheManager"/>

<!-- redis属性配置 -->

<bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig"> <property name="maxTotal" value="${redis.pool.maxTotal}" /> 

<property name="maxIdle" value="${redis.pool.maxIdle}" /> 

<property name="numTestsPerEvictionRun" value="${redis.pool.numTestsPerEvictionRun}" /> 

<property name="timeBetweenEvictionRunsMillis" value="${redis.pool.timeBetweenEvictionRunsMillis}" /> 

<property name="minEvictableIdleTimeMillis" value="${redis.pool.minEvictableIdleTimeMillis}" /> 

<property name="softMinEvictableIdleTimeMillis" value="${redis.pool.softMinEvictableIdleTimeMillis}" /> 

<property name="maxWaitMillis" value="${redis.pool.maxWaitMillis}" /> <property name="testOnBorrow" value="${redis.pool.testOnBorrow}" /> </bean>

<!-- redis集群配置 哨兵模式 -->

<bean id="sentinelConfiguration" class="org.springframework.data.redis.connection.RedisSentinelConfiguration"> 

<property name="master"> 

<bean class="org.springframework.data.redis.connection.RedisNode"> 

<!--这个值要和Sentinel中指定的master的值一致,不然启动时找不到Sentinel会报错的--> 

<property name="name" value="mymaster"></property> 

</bean> 

</property>

 <!--记住了,这里是指定Sentinel的IP和端口,不是Master和Slave的--> 

<property name="sentinels"> 

<set> 

<bean class="org.springframework.data.redis.connection.RedisNode"> 

<constructor-arg name="host" value="${redis.sentinel.host1}"></constructor-arg>

 <constructor-arg name="port" value="${redis.sentinel.port1}"></constructor-arg> 

</bean> 

<bean class="org.springframework.data.redis.connection.RedisNode"> 

<constructor-arg name="host" value="${redis.sentinel.host2}"></constructor-arg> 

<constructor-arg name="port" value="${redis.sentinel.port2}"></constructor-arg> 

</bean> 

</set> 

</property> 

</bean> 

<bean id="redisConnectionFactory" class="org.springframework.data.redis.connection.RedisConnectionFactory"> 

<constructor-arg name="sentinelConfig" ref="sentinelConfiguration"></constructor-arg> 

<constructor-arg name="poolConfig" ref="jedisPoolConfig"></constructor-arg> 

</bean> 

<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate"> 

<property name="connectionFactory" ref="redisConnectionFactory"></property> 

</bean>

<!-- 缓存管理器 --> 

<bean id="cacheManager" class="org.springframework.data.redis.cache.RedisCacheManager"> <constructor-arg ref="redisTemplate" /> 

</bean>

特别说明: 
1、Sentinel的集群模型,在Java端配置时,只需要指定有哪些Sentinel就可以了,不需要指定Master和Slave,之前不清楚,导致启动一直报找不到可用的Sentinel 
2、在Spring配置文件中一定要增加<cache:annotation-driven cache-manager="cacheManager"/>注解声明,否则缓存不会生效,之前缓存一直不生效的原因就是这个 
3、<cache:annotation-driven/>cache-manager属性默认值是cacheManager,默认情况下可以不指定,如果我们的定义的CacheManager名称不是cacheManager,就需要显示指定; 
4、<cache:annotation-driven/> 的另一个属性是model,可选值是proxy和aspectj,默认是proxy,model=proxy时,只有当缓存方法在声名的类外部被调用时,spring cache才会生效,换句话说就是如果在同一个类中一个方法调用当前类的缓存方法,缓存不生效,而model=aspectj时就不会有这个问题;另外model=proxy时,@Cacheable等注解加在public方法上,缓存才会生效,加在private上是不会生效的,而model=aspectj时也不会有这个问题
5、<cache:annotation-driven/> 还可以指定一个proxy-target-class属性,表示是否要代理class,默认为false。@Cacheable、@cacheEvict等也可以标注在接口上,这对于基于接口的代理来说是没有什么问题的,但要注意的是当设置proxy-target-class为true或者mode为aspectj时,是直接基于class进行操作的,定义在接口上的@Cacheable等Cache注解不会被识别到,对应的Spring Cache也不会起作用

以上准备工作完成后,就可以在Java代码中使用Redis了,很多人是以硬编码的方式在代码中使用缓存,这种对业务代码的侵入性是很强的,不方便后期的维护和扩展,这里使用注解方式,只需要在类或方法名上增加注解就可以了

@Override 

@Cacheable(value="user")

public UserVO selectUserById(String userId) throws Exception {

return userDao.selectUserById(userId);

 }

4)自定义Key生成器 

默认生成器是SimpleKeyGenerator,生成的Key是经过HashCode转换过的,不能通过Key清除指定接口的缓存,因此需要我们自己实现Key生成器,增加Key生成器实现类CacheKeyGenerator,并实现KeyGenerator接口,代码如下:

public class CacheKeyGenerator implements KeyGenerator { 

@Override 

public Object generate(Object target, Method method, Object... params) {

StringBuilder key = new StringBuilder(); key.append(target.getClass().getName());

key.append(".");

key.append(method.getName());

return key.toString();

}

}

这里Key的生成规则是类的限定名+方法名,可以确保在同一项目中,key不会重名,如果还需要把查询条件也作为Key的一部分,可以把params加进来

 

Key生成器需要配置在applicationContext.xml文件中,如下

<!-- 启动缓存注解功能,否则缓解不会生效,并自定义Key生成策略 -->

 <cache:annotation-driven cache-manager="cacheManager" key-generator="cacheKeyGenerator"/> 

<bean id="cacheKeyGenerator" class="com.bug.common.CacheKeyGenerator"></bean>

 原文地址:http://blog.csdn.net/kity9420/article/details/53571718


  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值