-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
一个关于 redis 长链接的问题 #1615
Comments
我想类似的 issue 是这个:#275 。是你描述的问题吗? |
我看了下,和 #139 这个 issue 比较像,看起来是 node 本身不支持 tcp_keepalive_intvl 和 tcp_keepalive_probes 两个参数的配置,所以 ioredis 也没办法支持。因此连接断开基本需要消耗 75* 9 = 11 min。 看来只能通过在客户端侧添加心跳主动去断开连接来实现了,晚点试下看看,多谢大神。 |
这里没发现更好的方式解决这个问题,下面是我解决这个问题的代码 const delay = (t, v) => new Promise((resolve, reject) => {
setTimeout(reject.bind(null, v), t);
});
const heartBeatFunc = async () => {
let serverStatus;
try {
serverStatus = await Promise.race([
client.ping('isAlive'),
delay(5000, 'Ping command timeout'),
]);
} catch (error) {
app.coreLogger.error('[egg-data:redis] ping 报错', error);
}
app.coreLogger.info(`server status: ${serverStatus}`);
if (!['isAlive', 'pong', 'PONG'].includes(serverStatus)) {
app.coreLogger.info(`ping status: ${serverStatus} connection disconnect`);
await client.disconnect();
await client.connect();
}
};
if (app.config.eggData.heartbeat.enable) {
let beat = app.config.eggData.heartbeat.interval;
beat = beat > 0 ? beat : 30;
schedule.scheduleJob(`*/${beat} * * * * *`, () => {
heartBeatFunc();
});
} |
我们在使用 ioredis 过程中遇到一个问题,连接的 redis 服务是通过 nginx 四层负载做的主从切换的代理,如果 redis1 可以连通就直接连接 redis1,否则切换到 redis2。但是 node 客户端永远都去连接 nginx:6379。
现在遇到一个问题,就是当 redis1 挂掉以后(比如直接电源关机),这个时候 node 客户端这边大约要等10 分钟左右才能成功连接成功,中间一直 hold 没反应。这个我们测试了下和客户端本身的 tcp.keepalive 配置有关:
net.ipv4.tcp_keepalive_time=7200
net.ipv4.tcp_keepalive_intvl=75
net.ipv4.tcp_keepalive_probes=9
感觉像是 75 * 9 的时间,确实把系统这个参数改小可以短时间内完成切换。
我们全局 redis 只用了一个长链接,也没有什么连接池之类的,不知道大神之前遇到过类似问题吗?java 相关的服务使用连接池好像没这个问题,我们 redis 配置如下:
想问下有没有遇到过类似的情况?
The text was updated successfully, but these errors were encountered: