在 Windows Server 2019 上,我在 WSL 下错误地运行了redis-server
第二次,它没有报告绑定侦听套接字失败。以下是输出netstat
:
C:\Users\Administrator>netstat -ano | grep 6379 | grep LISTEN
TCP 0.0.0.0:6379 0.0.0.0:0 LISTENING 11080
TCP 127.0.0.1:6379 0.0.0.0:0 LISTENING 13292
TCP [::]:6379 [::]:0 LISTENING 11080
TCP [::1]:6379 [::]:0 LISTENING 13292
两个问题:
- 这怎么可能呢?
- 我如何选择使用哪个实例进行连接
redis-cli
?
谢谢。
编辑
我又运行了第三次来检查,netstat
结果如下:
C:\Users\Administrator>netstat -ano | grep 6379 | grep LISTEN
TCP 0.0.0.0:6379 0.0.0.0:0 LISTENING 13916
TCP 0.0.0.0:6379 0.0.0.0:0 LISTENING 11080
TCP 127.0.0.1:6379 0.0.0.0:0 LISTENING 13292
TCP [::]:6379 [::]:0 LISTENING 11080
TCP [::]:6379 [::]:0 LISTENING 13916
TCP [::1]:6379 [::]:0 LISTENING 13292
答案1
如果插座有重用地址设置标志,那么多个进程将能够绑定到给定的端口。
“使用SO_REUSEADDR
和SO_EXCLUSIVEADDRUSE
“
使用
SO_REUSEADDR
socket
SO_REUSEADDR
选项允许一个套接字强制绑定到另一个套接字正在使用的端口。第二个套接字调用 setsockopt 并将 optname 参数设置为,将SO_REUSEADDR
optval 参数设置为布尔值 TRUE,然后在与原始套接字相同的端口上调用 bind。
这是为了允许服务在多个独立进程之间共享负载,并且只有服务能够正确处理时才应使用...Redis 很可能是支持此功能的服务之一(并默认启用它)。
看net.c
:
static int redisSetReuseAddr(redisContext *c) {
int on = 1;
if (setsockopt(c->fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) == -1) {
__redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL);
redisNetClose(c);
return REDIS_ERR;
}
return REDIS_OK;
}
static int redisCreateSocket(redisContext *c, int type) {
redisFD s;
if ((s = socket(type, SOCK_STREAM, 0)) == REDIS_INVALID_FD) {
__redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL);
return REDIS_ERR;
}
c->fd = s;
if (type == AF_INET) {
if (redisSetReuseAddr(c) == REDIS_ERR) {
return REDIS_ERR;
}
}
return REDIS_OK;
}
如果你需要确定你连接的是哪个服务器,你可以使用 Redis 命令INFO server
,并查找该process_id
字段。
或者,您可以netstat -ano
在 Windows 上使用(netstat -tnp
在 Linux 上)来确定给定客户端端口的服务器 PID(但不是客户端 PID)。
我不相信存在一种简单的操作系统级方法来确定这种关系。
如果您有多个服务器实例,每个实例使用不同的配置和/或数据,则会出现配置错误,你应该纠正 - 即:不要同时运行多个服务,或者对每个服务使用不同的端口。
这不是 Redis 负责的事情,就像选择监听端口也不是 Redis 负责的事情一样。