本文側重于springboot內建,redis哨兵模式的搭建請參考其他文章。
前置條件
一主二從redis和三個哨兵,springboot環境。
連接配接測試
先寫一個小demo來測試一個哨兵模式是否能夠通路。
public class test1 {
public static void main(String[] args) throws Exception {
test1.testSentinel();
}
public static void testSentinel() throws Exception {
String masterName = "mymaster";
Set<String> sentinels = new HashSet<>();
//三個哨兵
sentinels.add("127.0.0.1:26379");
sentinels.add("127.0.0.1:26380");
sentinels.add("127.0.0.1:26381");
JedisSentinelPool pool = new JedisSentinelPool(masterName, sentinels);
Jedis jedis = pool.getResource();
jedis.set("key1", "value1");
pool.close();
}
}
運作,我在調試過程中遇到的問題:
問題1:
All sentinels down, cannot determine where is mymaster master is running
解決方式:将redis哨兵配置檔案的bind 127.0.0.1注釋掉
問題2:
java.net.SocketException: Connection reset by peer: socket write error
解決方法:redis哨兵配置檔案中新增一行 protected-mode no
表明不已保護模式運作。
更改完配置以後重新開機redis哨兵,運作正常,測試完畢。
接下來進行springboot內建。
springboot內建
pom依賴:
<!--jedis-->
<!-- <dependency>-->
<!-- <groupId>redis.clients</groupId>-->
<!-- <artifactId>jedis</artifactId>-->
<!-- <version>2.9.0</version>-->
<!-- </dependency>-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-redis</artifactId>
<version>1.4.7.RELEASE</version>
</dependency>
兩者不相容或版本号不相容
同時引入有可能會導緻JedisConnectionFactory連接配接出錯
redis配置:
@Configuration
@EnableAutoConfiguration
public class RedisConfig extends CachingConfigurerSupport {
private static Logger logger = LoggerFactory.getLogger(RedisConfig.class);
@Value("#{'${spring.redis.sentinel.nodes}'.split(',')}")
private List<String> nodes;
@Value("${spring.redis.sentinel.nodes}")
private String redisNodes;
@Value("${spring.redis.sentinel.master}")
private String master;
//JedisPoolConfig配置連接配接池,配置空閑數和連接配接數,info clients 檢視連接配接數,client list 檢視詳情
@Bean
public JedisPoolConfig getRedisConfig(){
JedisPoolConfig jpc=new JedisPoolConfig();
jpc.setMaxIdle(10);//最大空閑
jpc.setMaxTotal(30);//最大連接配接
return jpc;
}
//RedisSentinelConfiguration配置哨兵模式,配置哨兵ip和端口,master主機
@Bean
public RedisSentinelConfiguration sentinelConfiguration(){
RedisSentinelConfiguration redisSentinelConfiguration = new RedisSentinelConfiguration();
//配置matser的名稱
redisSentinelConfiguration.master(master);
//配置redis的哨兵sentinel
Set<RedisNode> redisNodeSet = new HashSet<>();
nodes.forEach(x->{
redisNodeSet.add(new RedisNode(x.split(":")[0],Integer.parseInt(x.split(":")[1])));
});
logger.info("redisNodeSet -->"+redisNodeSet);
redisSentinelConfiguration.setSentinels(redisNodeSet);
return redisSentinelConfiguration;
}
//JedisConnectionFactory配置連接配接工廠
@Bean
public JedisConnectionFactory jedisConnectionFactory(JedisPoolConfig jedisPoolConfig,RedisSentinelConfiguration sentinelConfig) {
JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory(sentinelConfig,jedisPoolConfig);
return jedisConnectionFactory;
}
@Bean
public RedisTemplate<String, Object> redisTemplate(JedisConnectionFactory jedisConnectionFactory) {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<String, Object>();
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
redisTemplate.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());
redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());
redisTemplate.setConnectionFactory(jedisConnectionFactory);
return redisTemplate;
}
}
RedisTemplate用于處理複雜資料類型,比如對象,集合。預設采用是jdk序列化政策。
StringRedisTemplate用于處理字元串類型,預設采用的是String序列化政策
RedisTemplate用于處理複雜資料類型時需要配置序列化,否則運作時報錯
參考文章:https://blog.csdn.net/yifanSJ/article/details/79513179
調用:
@RestController
@RequestMapping("user")
public class LoginController {
@Autowired
private RedisTemplate redisTemplate;
@PostMapping("/login")
public String login(String password,String username){
ValueOperations<String, String> valueOperations = redisTemplate.opsForValue();
valueOperations.set("ycx","aaa");
}
}
在這裡添加了一個資料,去redis中檢視,發現都存在。
斷掉主伺服器,過段時間再執行去添加其他内容,發現存在,內建完畢。