java - Java 客户端无法连接到在 localhost 上运行的 Redis Sentinel
问题描述
我在本地主机中设置了 3 个 Redis 服务器和 3 个 Redis Sentinel 实例。服务器运行在:
127.0.0.1:6379 // Master
127.0.0.1:6380 // Slave
127.0.0.1:6381 // Slave
哨兵正在运行:
127.0.0.1:5000
127.0.0.1:5001
127.0.0.1:5002
我有一个(Java)客户端,它尝试连接到其中一个哨兵并在 redis 服务器中设置密钥:
// import statements
public class RedisPush {
private static final String MASTER_NAME = "mymaster";
private static final String PASSWORD = "foobared";
private static final Set sentinels;
static {
sentinels = new HashSet();
sentinels.add("127.0.0.1:5000");
sentinels.add("127.0.0.1:5001");
sentinels.add("127.0.0.1:5002");
}
public static void pushToRedis() {
Jedis jedis = null;
try {
JedisSentinelPool pool = new JedisSentinelPool(MASTER_NAME, sentinels);
System.out.println("Fetching connection from pool.");
jedis = pool.getResource();
jedis.auth(PASSWORD);
Socket socket = jedis.getClient().getSocket();
System.out.println("Connected to " + socket.getRemoteSocketAddress());
int i = 0;
while (true) {
jedis.set("sentinel_key" + i, "value" + i);
System.out.println(i);
i++;
Thread.sleep(1000);
}
} catch (Exception e) {
e.printStackTrace();
}
finally {
if(jedis != null)
jedis.close();
}
}
public static void main(String[] args) throws Exception {
while(true) {
pushToRedis();
Thread.sleep(1000);
}
}
}
最初,我的哨兵配置如下(例如,在 port 上运行的第一个哨兵5000
):
bind 127.0.0.1
port 5000
sentinel monitor mymaster 127.0.0.1 6379 2
sentinel down-after-milliseconds mymaster 5000
sentinel failover-timeout mymaster 60000
sentinel auth-pass mymaster foobared
如果我尝试运行我的 (Java) 客户端,我会收到以下错误:
Nov 23, 2018 1:52:57 AM redis.clients.jedis.JedisSentinelPool initSentinels
INFO: Trying to find master from available Sentinels...
Nov 23, 2018 1:52:57 AM redis.clients.jedis.JedisSentinelPool initSentinels
WARNING: Cannot get master address from sentinel running @ 192.168.0.102:5001. Reason: redis.clients.jedis.exceptions.JedisConnectionException: java.net.ConnectException: Connection refused (Connection refused). Trying next one.
Nov 23, 2018 1:52:57 AM redis.clients.jedis.JedisSentinelPool initSentinels
WARNING: Cannot get master address from sentinel running @ 192.168.0.102:5000. Reason: redis.clients.jedis.exceptions.JedisConnectionException: java.net.ConnectException: Connection refused (Connection refused). Trying next one.
Nov 23, 2018 1:52:57 AM redis.clients.jedis.JedisSentinelPool initSentinels
WARNING: Cannot get master address from sentinel running @ 192.168.0.102:5002. Reason: redis.clients.jedis.exceptions.JedisConnectionException: java.net.ConnectException: Connection refused (Connection refused). Trying next one.
redis.clients.jedis.exceptions.JedisConnectionException: All sentinels down, cannot determine where is mymaster master is running...
at redis.clients.jedis.JedisSentinelPool.initSentinels(JedisSentinelPool.java:180)
at redis.clients.jedis.JedisSentinelPool.<init>(JedisSentinelPool.java:95)
at redis.clients.jedis.JedisSentinelPool.<init>(JedisSentinelPool.java:82)
at redis.clients.jedis.JedisSentinelPool.<init>(JedisSentinelPool.java:70)
at redis.clients.jedis.JedisSentinelPool.<init>(JedisSentinelPool.java:44)
at RedisPush.pushToRedis(RedisPush.java:29)
at RedisPush.main(RedisPush.java:61)
但是,如果我将我的哨兵配置脚本更改为以下脚本:
# bind 127.0.0.1
port 5000
protected-mode no
sentinel monitor mymaster 127.0.0.1 6379 2
sentinel down-after-milliseconds mymaster 5000
sentinel failover-timeout mymaster 60000
sentinel auth-pass mymaster foobared
客户端完美运行。我不明白为什么。
AFAIK,如果requirepass
没有在文件中设置并且在sentinel.conf
文件bind
中被注释sentinel.conf
,那么只有这样protected-mode
才能yes
避免任何客户端连接到除了localhost
. 在我的第一个哨兵配置中,我有bind
命令但它仍然不起作用。
为什么注释掉bind
并明确设置protected-mode
为no
有效?
PS我也试过两者都有bind 127.0.0.1
,protected-mode no
但即使这样也没有用。
解决方案
我有一个类似的问题,Jedis 抛出了同样的错误,它与https://github.com/xetorthio/jedis/issues/1367有关
为了在我的 Mac 上解决这个问题,我做了sudo ifconfig lo0 alias 127.0.1.1
然后将我的 sentinel.conf 更改为bind 127.0.1.1
然后更新我的 yaml 以获取 spring 数据以连接到该 IP
sentinel.nodes: 127.0.1.1:5000, 127.0.1.1:5002, 127.0.1.1:5003
推荐阅读
- java - 依赖注入可以被认为是工厂方法模式的替代品吗?
- json - 构建基于 JSON 数组的 LINQ 查询
- quotes - 如何使用java排除检查引号中的单词
- angular - Firestore DocumentReference 类型检查不匹配
- python - 如何创建 Conda 包/应用程序的入口点?
- amazon-web-services - DynamoDB 本地数据库限制 - 用于初始 beta-go-live
- c - C代码中的字母顺序错误
- ios - 通过扩展添加时 UIViewController 的便利初始化不出现
- java - MongoDB 3.6 ClientCursor :: staticYield 无法解锁递归锁 ns 的 b/c:
- docker - Docker ADD 和卷冲突