spring boot配置同時支援單機和叢集redis
阿新 • • 發佈:2018-12-25
正式環境都是用叢集版redis,開發用的單機版,領導要求通過配置檔案來確定是單機還是叢集,由於單機版已經實現了,那麼準備就在單機版基礎上進行開發,然後發現spring boot1.2版本已經比較老,就升級版本,由於升級了spring boot版本,對應其他配置也進行了修改。最終修改的配置如下:
pom.xml
<properties> <java.version>1.8</java.version> <spring.version>4.3.9.RELEASE</spring.version> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.8.RELEASE</version> </parent> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> <!--原來是spring-boot-starter-redis--> </dependency> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>2.9.0</version> </dependency>
redis.properties檔案基本沒有變:
# REDIS (RedisProperties)
# Redis伺服器地址(叢集用逗號分隔)
#spring.redis.host=xxx.xxx.xxx.xxx:xxxxx
spring.redis.host=xxx.xxx.xxx.xxx:xxxxx,xxx.xxx.xxx.xxx:xxxxx
# Redis伺服器連線密碼(預設為空)
spring.redis.password=123456
# 連線超時時間(毫秒)
spring.redis.timeout=2000
spring.redis.max-redirects=8
注意:host變成ip:port,叢集多個ip和埠用“,”分割,為什麼這樣寫spring框架中RedisClusterConfiguration類中就是這樣分割。看一下原始碼:
//RedisClusterConfiguration類: private static final String REDIS_CLUSTER_NODES_CONFIG_PROPERTY = "spring.redis.cluster.nodes"; //預設是配置這樣的 …… public RedisClusterConfiguration(PropertySource<?> propertySource) { notNull(propertySource, "PropertySource must not be null!"); this.clusterNodes = new LinkedHashSet<RedisNode>(); //有spring.redis.cluster.nodes配置,分割這個屬性,新增node if (propertySource.containsProperty(REDIS_CLUSTER_NODES_CONFIG_PROPERTY)) { appendClusterNodes(commaDelimitedListToSet(propertySource.getProperty(REDIS_CLUSTER_NODES_CONFIG_PROPERTY) .toString())); } …… } //函式會呼叫,用","分割: public static String[] commaDelimitedListToStringArray(String str) { return delimitedListToStringArray(str, ","); } //然後用":"分割組裝成RedisNode private void appendClusterNodes(Set<String> hostAndPorts) { for (String hostAndPort : hostAndPorts) { addClusterNode(readHostAndPortFromString(hostAndPort)); } } private RedisNode readHostAndPortFromString(String hostAndPort) { String[] args = split(hostAndPort, ":"); notNull(args, "HostAndPort need to be seperated by ':'."); isTrue(args.length == 2, "Host and Port String needs to specified as host:port"); return new RedisNode(args[0], Integer.valueOf(args[1]).intValue()); }
在cacheconfig類中變成這樣的:
@Bean
public RedisClusterConfiguration getClusterConfiguration() {
if (host.split(",").length > 1) {
//如果是host是叢集模式的才進行以下操作
Map<String, Object> source = new HashMap<String, Object>();
source.put("spring.redis.cluster.nodes", host);
source.put("spring.redis.cluster.timeout", timeout);
source.put("spring.redis.cluster.max-redirects", redirects);
//在原始碼的註釋中可以看到是這樣配置,以為這樣寫就不用在Connection中不用在認證,後來確定太天真了
source.put("spring.redis.cluster.password", password);
return new RedisClusterConfiguration(new
MapPropertySource("RedisClusterConfiguration", source));
} else {
return null;
}
}
@Bean
public JedisConnectionFactory jedisConnectionFactory() {
if (host.split(",").length == 1) {
JedisConnectionFactory factory = new JedisConnectionFactory();
factory.setHostName(host.split(":")[0]);
factory.setPort(Integer.valueOf(host.split(":")[1]));
factory.setPassword(password);
factory.setTimeout(timeout);
return factory;
} else {
JedisConnectionFactory jcf = new JedisConnectionFactory(getClusterConfiguration());
jcf.setPassword(password); //叢集的密碼認證
return jcf;
}
}
//這樣改造之後,redisTemplate模板就不用改了,之前寫的redisUtil類也不用變了