Redis高可用哨兵模式,为了安全,也会添加认证
# 检查Redis哨兵模式下master节点命令 $ SENTINEL get-master-addr-by-name mymaster
所以,我们在Java中连接Redis时,就需要配置两种密码;
1. 连接哨兵的认证密码: sentinelPassword
2. 哨兵返回的master节点密码:redisPassword
针对以上问题,我们选择连接Redis的库为Jedis: redis/jedis: A blazingly small and sane redis java client (github.com)
代码如下:
private static void createJedisPool() { JedisPoolConfig config = new JedisPoolConfig(); config.setMaxTotal(MAX_TOTAL); config.setMaxIdle(MAX_IDLE); config.setMaxWaitMillis(MAX_WAIT_MILLIS); config.setTestOnBorrow(TEST_ON_BORROW); config.setTestWhileIdle(TEST_WHILE_IDLE); config.setTestOnReturn(TEST_ON_RETURN); String masterName = "mymaster"; Set<String> sentinels = new HashSet<String>(); sentinels.add(new HostAndPort("10.0.0.13", 26379).toString()); sentinels.add(new HostAndPort("10.0.0.14", 26379).toString()); sentinels.add(new HostAndPort("10.0.0.15", 26379).toString()); String password = "redisPassword"; // 连接redis时master节点认证密码 String sentinelPassword = "sentinelPassword"; // 连接sentinel时的认证密码 // sentinel no auth // pool = new JedisSentinelPool(masterName, sentinels, config, TIMEOUT, password, 0);
// sentinel need auth pool = new JedisSentinelPool(masterName, sentinels, password, sentinelPassword); }
但是怎么调试都不行,看了代码实现
public JedisSentinelPool(String masterName, Set<String> sentinels, GenericObjectPoolConfig<Jedis> poolConfig, int connectionTimeout, int soTimeout, int infiniteSoTimeout, String user, String password, int database, String clientName, int sentinelConnectionTimeout, int sentinelSoTimeout, String sentinelUser, String sentinelPassword, String sentinelClientName) { this(masterName, sentinels, poolConfig, new JedisFactory(connectionTimeout, soTimeout, infiniteSoTimeout, user, password, database, clientName)); this.connectionTimeout = connectionTimeout; this.soTimeout = soTimeout; this.infiniteSoTimeout = infiniteSoTimeout; this.user = user; this.password = password; this.database = database; this.clientName = clientName; this.sentinelConnectionTimeout = sentinelConnectionTimeout; this.sentinelSoTimeout = sentinelSoTimeout; this.sentinelUser = sentinelUser; this.sentinelPassword = sentinelPassword; this.sentinelClientName = sentinelClientName; } public JedisSentinelPool(String masterName, Set<String> sentinels, GenericObjectPoolConfig<Jedis> poolConfig, JedisFactory factory) { this(masterName, parseHostAndPorts(sentinels), poolConfig, (JedisFactory)factory, DefaultJedisClientConfig.builder().build()); } public JedisSentinelPool(String masterName, Set<HostAndPort> sentinels, GenericObjectPoolConfig<Jedis> poolConfig, JedisClientConfig masteClientConfig, JedisClientConfig sentinelClientConfig) { this(masterName, sentinels, poolConfig, new JedisFactory(masteClientConfig), sentinelClientConfig); } public JedisSentinelPool(String masterName, Set<HostAndPort> sentinels, GenericObjectPoolConfig<Jedis> poolConfig, JedisFactory factory, JedisClientConfig sentinelClientConfig) { super(poolConfig, factory); this.masterListeners = new HashSet(); this.initPoolLock = new Object(); this.poolConfig = poolConfig; this.factory = factory; this.sentinelClientConfig = sentinelClientConfig; HostAndPort master = this.initSentinels(sentinels, masterName); this.initMaster(master); }
发现在 this.initSentinels(sentinels, masterName); 时,确实没有将哨兵的密码传入;所以我们就到官方仓库去查看;发现官方的里面是有传入哨兵密码信息的;
所以,我们就更新了jedis的依赖版本;【jedis 3.6.0 是没有解决的,只有3.6.*是否解决没有测试,3.7.0是解决了】
<!-- jedis --> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>3.7.0</version> </dependency>
解决之后的代码如下:
public JedisSentinelPool(String masterName, Set<String> sentinels, GenericObjectPoolConfig<Jedis> poolConfig, int connectionTimeout, int soTimeout, int infiniteSoTimeout, String user, String password, int database, String clientName, int sentinelConnectionTimeout, int sentinelSoTimeout, String sentinelUser, String sentinelPassword, String sentinelClientName) { this(masterName, parseHostAndPorts(sentinels), poolConfig, (JedisClientConfig)DefaultJedisClientConfig.builder().connectionTimeoutMillis(connectionTimeout).socketTimeoutMillis(soTimeout).blockingSocketTimeoutMillis(infiniteSoTimeout).user(user).password(password).database(database).clientName(clientName).build(), DefaultJedisClientConfig.builder().connectionTimeoutMillis(sentinelConnectionTimeout).socketTimeoutMillis(sentinelSoTimeout).user(sentinelUser).password(sentinelPassword).clientName(sentinelClientName).build()); this.connectionTimeout = connectionTimeout; this.soTimeout = soTimeout; this.infiniteSoTimeout = infiniteSoTimeout; this.user = user; this.password = password; this.database = database; this.clientName = clientName; this.sentinelConnectionTimeout = sentinelConnectionTimeout; this.sentinelSoTimeout = sentinelSoTimeout; this.sentinelUser = sentinelUser; this.sentinelPassword = sentinelPassword; this.sentinelClientName = sentinelClientName; } public JedisSentinelPool(String masterName, Set<String> sentinels, GenericObjectPoolConfig<Jedis> poolConfig, JedisFactory factory) { this(masterName, parseHostAndPorts(sentinels), poolConfig, (JedisFactory)factory, DefaultJedisClientConfig.builder().build()); } public JedisSentinelPool(String masterName, Set<HostAndPort> sentinels, JedisClientConfig masteClientConfig, JedisClientConfig sentinelClientConfig) { this(masterName, sentinels, new GenericObjectPoolConfig(), masteClientConfig, sentinelClientConfig); } public JedisSentinelPool(String masterName, Set<HostAndPort> sentinels, GenericObjectPoolConfig<Jedis> poolConfig, JedisClientConfig masteClientConfig, JedisClientConfig sentinelClientConfig) { this(masterName, sentinels, poolConfig, new JedisFactory(masteClientConfig), sentinelClientConfig); } public JedisSentinelPool(String masterName, Set<HostAndPort> sentinels, GenericObjectPoolConfig<Jedis> poolConfig, JedisFactory factory, JedisClientConfig sentinelClientConfig) { super(poolConfig, factory); this.masterListeners = new HashSet(); this.initPoolLock = new Object(); this.poolConfig = poolConfig; this.factory = factory; this.sentinelClientConfig = sentinelClientConfig; HostAndPort master = this.initSentinels(sentinels, masterName); this.initMaster(master); }
发现其实只要更新依赖包到最新就可以解决,囧