Spring 整合redis叢集 實現 以及過程中需要注意的問題點
一,準備工作:
1.首先安裝好redis叢集,啟動並配置叢集。
2.SpringMVC環境,看專案或個人需要,可以使SpringMVC的web專案,也可以是隻使用SpringBean管理器。
二,著手配置:
由於專案是由maven管理的所以需要的jar 包新增到maven 的pom檔案即可
1.新增jar依賴,再maven pom.xml 檔案中新增依賴如下:// 這裡需要說明下,依賴的jar包 redis.client 和 spring-data-redis 的版本匹配問題 實驗了好幾個對應如下:
redis.client 2.9.0 ---- spring-data-redis 1.7.1.RELEASE
redis.client 2.9.0 -----spring-data-redis 1.7.2.RELEASE 這兩個是可以使用的
由於版本不匹配,遇到的錯誤如下:
1. ClassNotFoundException : redis/client/util/geoUtils 說這個類找不到。
2. org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'redisTemplate' defined in class path resource [applicationContext.xml]
說建立 redisTemplate bean 物件時失敗了。
<!-- jedis (一個redis client端的jar)-->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
</dependency>
<!-- spring-data-redis 依賴-->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<version>1.7.1.RELEASE</version>
</dependency>
2.配置redis 配置檔案 我把它單獨提取出來放在一個配置檔案(spring-data-redis-cluster.xml)中,然後import 到 spring ApplicationContext.xml 檔案中:
spring-data-redis-cluster.xml 配置如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans" 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:task="http://www.springframework.org/schema/task" xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:cache="http://www.springframework.org/schema/cache"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.1.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.1.xsd
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-4.1.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd
http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd">
<!-- redis連線池 這裡引用的是jedis 包中的功能 -->
<bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
<property name="maxTotal" value="${redis.maxActive:1024}" />
<property name="maxIdle" value="${redis.maxIdle:1024}" />
<property name="maxWaitMillis" value="${redis.maxWait:10000}" />
<property name="testOnBorrow" value="${redis.testOnBorrow:true}" />
<property name="testOnReturn" value="${redis.testOnReturn:true}" />
</bean>
<!-- Redis叢集配置 這裡使用的是spring-data-redis 包中內容 -->
<bean id="redisClusterConfig" class="org.springframework.data.redis.connection.RedisClusterConfiguration">
<property name="maxRedirects" value="6"></property>
<property name="clusterNodes">
<set>
<bean class="org.springframework.data.redis.connection.RedisNode">
<constructor-arg name="host" value="192.168.1.105"></constructor-arg>
<constructor-arg name="port" value="7111"></constructor-arg>
</bean>
<bean class="org.springframework.data.redis.connection.RedisNode">
<constructor-arg name="host" value="192.168.1.105"></constructor-arg>
<constructor-arg name="port" value="7112"></constructor-arg>
</bean>
<bean class="org.springframework.data.redis.connection.RedisNode">
<constructor-arg name="host" value="192.168.1.105"></constructor-arg>
<constructor-arg name="port" value="7116"></constructor-arg>
</bean>
<bean class="org.springframework.data.redis.connection.RedisNode">
<constructor-arg name="host" value="192.168.1.102"></constructor-arg>
<constructor-arg name="port" value="7113"></constructor-arg>
</bean>
<bean class="org.springframework.data.redis.connection.RedisNode">
<constructor-arg name="host" value="192.168.1.102"></constructor-arg>
<constructor-arg name="port" value="7114"></constructor-arg>
</bean>
<bean class="org.springframework.data.redis.connection.RedisNode">
<constructor-arg name="host" value="192.168.1.102"></constructor-arg>
<constructor-arg name="port" value="7115"></constructor-arg>
</bean>
</set>
</property>
</bean>
<!-- Redis連線工廠 -->
<bean id="redis4CacheConnectionFactory"
class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
<constructor-arg name="clusterConfig" ref="redisClusterConfig" />
<property name="timeout" value="${redis.timeout:10000}" />
<property name="poolConfig" ref="jedisPoolConfig" />
</bean>
<!-- 儲存序列化 -->
<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>
</beans>
3.再ApplicationContent.xml 配置檔案中 匯入以上配置:
<!-- 匯入rediscluster配置檔案 -->
<import resource="classpath:spring-data-redis-cluster.xml" />
4.redisTemplate 的應用:
自定義一個redisClient類來管理操作 redis 的存取操作:我定義的是:RedisClusterClient.java 類,內容如下:
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import org.springframework.beans.factory.annotation.Autowired;
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.stereotype.Service;
import org.springframework.util.StringUtils;
@Service
public class RedisClusterClient {
// 由於在Spring ApplicationContext.xml 配置檔案中匯入了 redis的配置檔案,也就間接的將 <bean id="clusterRedisTemplate" class="org.springframework.data.redis.core.RedisTemplate"> 這個Bean託管給了Spring bean容器來管理所以
只要我使用註解就可以把這個模板類物件引用過來。
@Autowired
private RedisTemplate<String,String> clusterRedisTemplate;
//新增資料
public void put(Object key, Object value) {
if(null == value) {
return;
}
if(value instanceof String) {
if(StringUtils.isEmpty(value.toString())) {
return;
}
}
// TODO Auto-generated method stub
final String keyf = key + "";
final Object valuef = value;
final long liveTime = 86400;
clusterRedisTemplate.execute(new RedisCallback<Long>() {
public Long doInRedis(RedisConnection connection)
throws DataAccessException {
byte[] keyb = keyf.getBytes();
byte[] valueb = toByteArray(valuef);
connection.set(keyb, valueb);
if (liveTime > 0) {
connection.expire(keyb, liveTime);
}
return 1L;
}
});
}
// 獲取資料
public Object get(Object key) {
final String keyf = (String) key;
Object object;
object = clusterRedisTemplate.execute(new RedisCallback<Object>() {
public Object doInRedis(RedisConnection connection)
throws DataAccessException {
byte[] key = keyf.getBytes();
byte[] value = connection.get(key);
if (value == null) {
return null;
}
return toObject(value);
}
});
return object;
}
/**
* 描述 : <byte[]轉Object>. <br>
* <p>
* <使用方法說明>
* </p>
*
* @param bytes
* @return
*/
private Object toObject(byte[] bytes) {
Object obj = null;
try {
ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
ObjectInputStream ois = new ObjectInputStream(bis);
obj = ois.readObject();
ois.close();
bis.close();
} catch (IOException ex) {
ex.printStackTrace();
} catch (ClassNotFoundException ex) {
ex.printStackTrace();
}
return obj;
}
private byte[] toByteArray(Object obj) {
byte[] bytes = null;
ByteArrayOutputStream bos = new ByteArrayOutputStream();
try {
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(obj);
oos.flush();
bytes = bos.toByteArray();
oos.close();
bos.close();
} catch (IOException ex) {
ex.printStackTrace();
}
return bytes;
}
}