windows下的哨兵模式:
本地臨時(shí)搭建個(gè)哨兵模式使碾,1主1從2哨兵,就為了追求簡(jiǎn)單
redis下的master.conf:
port 6379
bind 172.20.61.25
requirepass 123456
redis下的slave.conf:
port 6380
bind 172.20.61.25
slaveof 172.20.61.25 6379
masterauth 123456
redis下下新建2個(gè)sentinel.conf腋么,重命名為sentinel1.conf,sentinel2.conf
sentinel1.conf的配置如下:
port 26379
sentinel myid aec78af18a33e0ae9cb0df056bfbb3a36dc90c3d
sentinel monitor mymaster 172.20.61.25 6379 1
sentinel down-after-milliseconds mymaster 5000
sentinel auth-pass mymaster 123456
protected-mode no
bind 172.20.61.25
sentinel2.conf的配置如下:
port 26479
sentinel myid 3303268336b86fc62d1d4875810b77c3466bd36d
sentinel monitor mymaster 172.20.61.25 6380 1
sentinel down-after-milliseconds mymaster 5000
sentinel auth-pass mymaster 123456
sentinel config-epoch mymaster 37
protected-mode no
bind 172.20.61.25
如果覺得2個(gè)哨兵不夠亥揖,可以自行添加哨兵珊擂,增加幾個(gè)sentinel.conf,配置其他都一樣费变,
sentinel monitor mymaster 172.20.61.25 6380 1 --這個(gè)ip改成你要監(jiān)聽的主reds或者從redis的ip和端口就行
說個(gè)遇到的坑
我之前的master.conf摧扇,slave.conf,sentinel1.conf,sentinel2.conf的ip都是用127.0.0.1,結(jié)果
All sentinels down, cannot determine where is mymaster master is running...
或者這個(gè)錯(cuò)
Could not get a resource from the pool
所以windows下把master.conf挚歧,slave.conf,sentinel1.conf,sentinel2.conf這些配置的ip全換成分配的ip,
windows下的cmd命令扛稽,ipconfig可疑查看一下自己電腦分配的ip。
我們的spring boot項(xiàng)目中定義了JedisPoolConfig 連接池滑负, 配置redis的哨兵和jedis的配置工廠
@Bean
public JedisPoolConfig jedisPoolConfig() {
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
// 最大空閑數(shù)
jedisPoolConfig.setMaxIdle(maxIdle);
// 連接池的最大數(shù)據(jù)庫(kù)連接數(shù)
jedisPoolConfig.setMaxTotal(maxTotal);
// 最大建立連接等待時(shí)間
jedisPoolConfig.setMaxWaitMillis(maxWaitMillis);
// 逐出連接的最小空閑時(shí)間 默認(rèn)1800000毫秒(30分鐘)
jedisPoolConfig.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
// 每次逐出檢查時(shí) 逐出的最大數(shù)目 如果為負(fù)數(shù)就是 : 1/abs(n), 默認(rèn)3
jedisPoolConfig.setNumTestsPerEvictionRun(numTestsPerEvictionRun);
// 逐出掃描的時(shí)間間隔(毫秒) 如果為負(fù)數(shù),則不運(yùn)行逐出線程, 默認(rèn)-1
jedisPoolConfig.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
// 是否在從池中取出連接前進(jìn)行檢驗(yàn),如果檢驗(yàn)失敗,則從池中去除連接并嘗試取出另一個(gè)
jedisPoolConfig.setTestOnBorrow(testOnBorrow);
// 在空閑時(shí)檢查有效性, 默認(rèn)false
jedisPoolConfig.setTestWhileIdle(testWhileIdle);
return jedisPoolConfig;
}
@Bean
public RedisSentinelConfiguration sentinelConfiguration() {
if(redisType==1){
RedisSentinelConfiguration redisSentinelConfiguration = new RedisSentinelConfiguration();
// 配置redis的哨兵sentinel
RedisNode senRedisNode = new RedisNode(sentinelHostName, sentinelport);
Set<RedisNode> redisNodeSet = new HashSet<>();
redisNodeSet.add(senRedisNode);
redisSentinelConfiguration.setSentinels(redisNodeSet);
redisSentinelConfiguration.setMaster(masterName);
redisSentinelConfiguration.setPassword(password);
return redisSentinelConfiguration;
}else {
return new RedisSentinelConfiguration();
}
@Bean
public JedisConnectionFactory jedisConnectionFactory(JedisPoolConfig jedisPoolConfig, RedisSentinelConfiguration sentinelConfig) {
if(redisType==1){
JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory(sentinelConfig, jedisPoolConfig);
return jedisConnectionFactory;
}else {
JedisPoolConfig config = jedisPoolConfig();
JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory(config);
jedisConnectionFactory.setHostName(host);
jedisConnectionFactory.setPassword(this.password);
jedisConnectionFactory.setPort(port);
jedisConnectionFactory.setTimeout(timeout);
return jedisConnectionFactory;
}
}
還有yml文件中的redis的一些配置
redis:
# 1:哨兵模式 其它數(shù)字:普通模式
type: 1
# 哨兵模式普通模式共用 最大空閑數(shù)
maxIdle: 200
# 哨兵模式普通模式共用 連接池的最大數(shù)據(jù)庫(kù)連接數(shù)在张。設(shè)為0表示無限制,如果是jedis 2.4以后用redis.maxTotal
maxTotal: 1000
# 哨兵模式普通模式共用 最大建立連接等待時(shí)間。如果超過此時(shí)間將接到異常橙困。設(shè)為-1表示無限制瞧掺。
maxWaitMillis : 1000
# 哨兵模式普通模式共用 連接的最小空閑時(shí)間 默認(rèn)1800000毫秒(30分鐘)
minEvictableIdleTimeMillis: 300000
# 哨兵模式普通模式共用 每次逐出檢查時(shí) 逐出的最大數(shù)目 如果為負(fù)數(shù)就是 : 1/abs(n), 默認(rèn)3
numTestsPerEvictionRun: 1024
# 哨兵模式普通模式共用 逐出掃描的時(shí)間間隔(毫秒) 如果為負(fù)數(shù),則不運(yùn)行逐出線程, 默認(rèn)-1
timeBetweenEvictionRunsMillis: 30000
# 哨兵模式普通模式共用 是否在從池中取出連接前進(jìn)行檢驗(yàn),如果檢驗(yàn)失敗,則從池中去除連接并嘗試取出另一個(gè)
testOnBorrow: true
# 哨兵模式普通模式共用 在空閑時(shí)檢查有效性, 默認(rèn)false
testWhileIdle: true
# 密碼 哨兵模式普通模式共用
password: 123456
# 普通模式 地址
host: 127.0.0.1
# 普通模式 連接超時(shí)時(shí)間(毫秒)
timeout: 5000
# 普通模式 端口
port: 6379
# 哨兵模式 哨兵masterName
mymaster:
masterName: mymaster
# 哨兵模式 哨兵地址 端口
sentinel:
hostName: 172.20.61.25
port: 26379
為啥不能用127.0.0.1這個(gè)ip
我跟蹤源碼,發(fā)現(xiàn)中間調(diào)用了這個(gè)方法
public static String convertHost(String host) {
return !host.equals("127.0.0.1") && !host.startsWith("localhost") && !host.equals("0.0.0.0") && !host.startsWith("169.254") && !host.startsWith("::1") && !host.startsWith("0:0:0:0:0:0:0:1") ? host : LOCALHOST_STR;
}
這個(gè)方法內(nèi)凡傅,如果你的配置文件ip是127.0.0.1,localhost,0.0.0.0等等上面中的某一個(gè)肠缔,那么他會(huì)LOCALHOST_STR代替你的ip
其實(shí)LOCALHOST_STR就是調(diào)用了getLocalHostQuietly方法夏跷,也就是InetAddress.getLocalHost().getHostAddress()得到ip來替換你配置文件的ip
public static String getLocalHostQuietly() {
String localAddress;
try {
localAddress = InetAddress.getLocalHost().getHostAddress();
} catch (Exception var2) {
log.logp(Level.SEVERE, HostAndPort.class.getName(), "getLocalHostQuietly", "cant resolve localhost address", var2);
localAddress = "localhost";
}
return localAddress;
}
所有會(huì)產(chǎn)生Could not get a resource from the pool這個(gè)錯(cuò)誤