在 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_REUSEADDR
和SO_EXCLUSIVEADDRUSE
」
使用
SO_REUSEADDR
套接字選項
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 負責的事情一樣。