這是我參與更文挑戰的第11天,活動詳情查看: 更文挑戰node
無心翻出多年前代碼發現當時真的是小年輕啊。對於redis集羣接入spring真的是搞了大半天。當時本身特地解決一個場景的bug 。就是redis集羣宕機以後自動從新捕獲最新集羣狀態。不過到如今本身再沒有使用過集羣了。因此當時的bug究竟是本身沒有配置好仍是的確存在。這個還須要筆者後續繼續驗證!!!redis
上一篇詳細的贅述了Redis的curd操做及集羣的搭建。下面咱們開始將他整合到咱們實際的項目中去。個人項目採用的是標準的ssm框架,ssm框架這裏不說,直接開始整合。spring
<!--1.7.2 開始支持Redis 集羣-->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<version>1.7.2.RELEASE</version>
</dependency>
<!-- Redis 緩存Jar -->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
</dependency>
<!--下面就是spring的maven座標了,這裏就不寫了,讀者本身引入-->
複製代碼
<bean id="redisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
<property name="maxTotal" value="${redis.maxTotal}" />
<property name="maxIdle" value="${redis.maxIdle}" />
<property name="maxWaitMillis" value="${redis.maxWait}" />
<property name="testOnBorrow" value="${redis.testOnBorrow}" />
</bean>
複製代碼
maxIdle:控制一個pool最多有多少個狀態爲idle的jedis實例;緩存
在borrow一個jedis實例時,是否提早進行alidate操做;若是爲true,則獲得的jedis實例均是可用的markdown
maxWaitMillis : 表示當borrow一個jedis實例時,最大的等待時間,若是超過等待時間,則直接拋出JedisConnectionException;框架
這裏咱們就是將咱們上一篇開啓的Redis服務引入到項目中來。clusterNodes就是咱們一個一個的Redis服務。maven
<!-- Redis集羣配置 -->
<bean id="redisClusterConfig" class="org.springframework.data.redis.connection.RedisClusterConfiguration">
<property name="maxRedirects" value="3"></property>
<property name="clusterNodes">
<set>
<bean class="org.springframework.data.redis.connection.RedisNode">
<constructor-arg name="host" value="127.0.0.1"></constructor-arg>
<constructor-arg name="port" value="7000"></constructor-arg>
</bean>
<bean class="org.springframework.data.redis.connection.RedisNode">
<constructor-arg name="host" value="127.0.0.1"></constructor-arg>
<constructor-arg name="port" value="7004"></constructor-arg>
</bean>
<bean class="org.springframework.data.redis.connection.RedisNode">
<constructor-arg name="host" value="127.0.0.1"></constructor-arg>
<constructor-arg name="port" value="7005"></constructor-arg>
</bean>
</set>
</property>
</bean>
複製代碼
咱們將上面的Redis服務節點和鏈接池引入到工廠中,有工程去生產一個可用的jedis提供咱們進行緩存的CURD操做!!post
<!-- ReDis鏈接工廠 -->
<bean id="redis4CacheConnectionFactory"
class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
<constructor-arg name="clusterConfig" ref="redisClusterConfig" />
<property name="timeout" value="${redis.timeout}" />
<property name="poolConfig" ref="redisPoolConfig" />
</bean>
複製代碼
提供了jedis進行操做咱們就要放道模板裏面給咱們調用!。性能
<!-- 存儲序列化 -->
<bean name="stringRedisSerializer"
class="org.springframework.data.redis.serializer.StringRedisSerializer" />
<!-- 集羣Resis使用模板 -->
<bean id="clusterRedisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
<property name="connectionFactory" ref="redis4CacheConnectionFactory" />
<property name="keySerializer" ref="stringRedisSerializer" />
<property name="hashKeySerializer" ref="stringRedisSerializer" />
<property name="valueSerializer" ref="stringRedisSerializer" />
<property name="hashValueSerializer" ref="stringRedisSerializer" />
</bean>
複製代碼
在配置文件中都已經將jedis配置好了,咱們只須要經過這個模板就能夠對Redis進行CURD操做了。下面是個簡單的列子spa
clusterRedisTemplate.execute(new RedisCallback<Long>() {
public Long doInRedis(RedisConnection connection)
throws DataAccessException {
byte[] keyb = key.getBytes();
byte[] valueb = toByteArray(value);
// 判斷當前值是否已經存在
if (connection.exists(keyb)) {
// 刪除原數據
connection.del(keyb);
}
connection.set(keyb, valueb);
return 1L;
}
});
複製代碼
在RedisClusterConfiguration類中咱們傳入的Redis服務node,咱們設置的是property而後該類中就開始執行下面代碼
而後咱們在工廠中傳入這些節點,
這個工廠給我提供了一個afterproperties方法,意思就是在這些參數設置完成以後執行的一個方法。
在這裏咱們能夠看見一個creatPool的方法,這個就是去鏈接池裏建立鏈接
上面的部署 會出現一個問題,就是在項目中,每次初始化時會重鏈接池中選擇一個可用的Redis服務鏈接,當這個Redis服務宕機後咱們的項目還會繼續鏈接這個Redis服務,咱們只能重新啓動項目,項目纔會重新從鏈接池中選擇新的Redis服務。
/** Redis模板注入 */
@Resource
private RedisClusterConfiguration redisClusterConfig;
private JedisConnectionFactory redis4CacheConnectionFactory;
@Resource
private RedisTemplate<String, Object> clusterRedisTemplate;
//重構鏈接池
private void init(){
redis4CacheConnectionFactory=new JedisConnectionFactory(redisClusterConfig);
redis4CacheConnectionFactory.afterPropertiesSet();
clusterRedisTemplate.setConnectionFactory(redis4CacheConnectionFactory);
}
複製代碼
這樣又出現問題了,每次都初始化鏈接池,這在鏈接池上很費性能,暫時沒有解決辦法,可是我初步想經過redis sentinel 來檢測Redis集羣中的Redis服務。當Redis宕機後經過sentinel 提供的API來通知項目從新去構建鏈接池,從新鏈接新Redis服務