redis的主從複製我就不贅述了,各大博客都有寫怎麼配置的,我們來講SpringBoot怎麼配置讀寫分離:
方法應該有多種:可能的實現有利用AOP動態的獲取redis連接工廠並注入對應的實例
本文的實現比較呆板,讀寫分離,主redis負責寫,從redis負責讀,有兩個java配置類如下:
附加:java Config(java配置類)是Spring的一種編碼風格,其他兩種編碼風格爲XML和註解,Java Config風格在SpringBoot中搭配註解風格同時使用;
Maven需要引入的依賴:
<!--redis依賴-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!-- redis集羣使用 -->
<dependency>
<!-- springboot的parents依賴中有對版本號的控制,此處不需要添加版本號相關信息 -->
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
主redis對應的配置類:
package com.wang.ms.config;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import redis.clients.jedis.JedisPoolConfig;
//主redis對應的配置類
@Configuration
public class MasterRedisConfig {
//Redis連接池配置
@Bean
public JedisPoolConfig jedisPoolConfig(){
JedisPoolConfig masterConfig=new JedisPoolConfig();
masterConfig.setMaxTotal(1000);
masterConfig.setMaxIdle(1000);
masterConfig.setMaxWaitMillis(3000);
return masterConfig;
}
//redis主連接工廠
@Bean("masterRedisFactory")
@Primary
public JedisConnectionFactory masterJedisConnectionFactory(JedisPoolConfig jedisPoolConfig){
JedisConnectionFactory masterFactory=new JedisConnectionFactory();
masterFactory.setPort(6381);
masterFactory.setHostName("192.168.199.128");
masterFactory.setPoolConfig(jedisPoolConfig);
masterFactory.setTimeout(3000);
return masterFactory;
}
//構造redis主對應的Template
@Bean("masterRedisTemplate")
@Primary
public RedisTemplate masterRedisTemplate(@Qualifier("masterRedisFactory") JedisConnectionFactory jedisConnectionFactory){
RedisTemplate masterRedisTemplate=new RedisTemplate();
masterRedisTemplate.setConnectionFactory(jedisConnectionFactory);
masterRedisTemplate.setKeySerializer(new StringRedisSerializer());
masterRedisTemplate.setValueSerializer(new JdkSerializationRedisSerializer());
return masterRedisTemplate;
}
}
從redis對應的配置類:
package com.wang.ms.config;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import redis.clients.jedis.JedisPoolConfig;
@Configuration
//從redis對應的配置類
public class SlaveRedisConfig {
@Bean("slaveRedisFactory")
public JedisConnectionFactory slaveJedisConnectionFactory(JedisPoolConfig jedisPoolConfig){
JedisConnectionFactory slaveFactory=new JedisConnectionFactory();
slaveFactory.setPort(6379);
slaveFactory.setHostName("192.168.199.128");
slaveFactory.setPoolConfig(jedisPoolConfig);
slaveFactory.setTimeout(3000);
return slaveFactory;
}
@Bean("slaveRedisTemplate")
public RedisTemplate slaveRedisTemplate(@Qualifier("slaveRedisFactory") JedisConnectionFactory jedisConnectionFactory){
RedisTemplate slaveRedisTemplate=new RedisTemplate();
slaveRedisTemplate.setConnectionFactory(jedisConnectionFactory);
slaveRedisTemplate.setKeySerializer(new StringRedisSerializer());
slaveRedisTemplate.setValueSerializer(new JdkSerializationRedisSerializer());
return slaveRedisTemplate;
}
}
注意,我的redis主的端口是6381,redis從的端口是6379,@Primary不能缺省,即使形參注入時用了@Qualifier()也不能省,因爲SpringBoot的AutoRedisConfig(一個Springboot的內部自動配置redis類沒有用@Qualifier指定注入哪個redis連接工廠,所以當你項目中有兩個redis連接工廠時,SpringBoot會報錯,提示發現了兩個工廠bean,但只期望一個),@Primary代表這個bean爲主bean,如果有相同類型的bean,優先注入這個bean;
如果開啓SpringBoot時報錯:
redis.clients.jedis.exceptions.JedisConnectionException:
java.net.ConnectException: Connection refused: connect
因爲我的redis主從都在虛擬機(Linux)上,redis.conf默認配置是bind 127.0.0.1,他只會監聽本機(虛擬機)的端口並接受本機(虛擬機上)的客戶端訪問,而我現在的應用在主機(Windows)上,他要去訪問虛擬機上的redis,則redis應該開啓對ip(圖中例子192.168.199.128,也就是虛擬機自己所在的ip地址)的監聽,本地項目才能通過192.168.199.128去訪問到虛擬機上的redis服務端口;
測試寫入redis:
測試redis讀出: