redis连接断开

背景

va_list的bug,修改后,在开发环境验证时,发现执行redisCommand函数时,会卡住,直到进程被杀掉重启。为啥生产环境直接进入了第二次循环,没有卡住呢?

两种情况

  • redis没有切过master,老的连接有时也不能用,报错Connection reset by peer,这时会自动重连,大概一天2次这种报错,为啥连接会中断,这个还没找到原因。
  • 为何我验证的情景下,请求老的连接时会卡住呢?是因为我是通过封禁redis端口的方法触发redis切换的。切换master后,分两种情况:
  1. redis之前的master变成了slave,再次请求时,报错server closed the connection redis,这种情况也会自动重连。

  2. 如果把master的端口禁用,redis切换master后,业务模块再请求之前的连接会卡住,这种情况需要设置超时时间。

    1
    2
    3
    4
    5
    6
    iRet = redisSetTimeout(m_pstRedisLink, timeout);
    if(iRet != 0)
    {
    m_strErrMsg = "redis set timeout fail";
    return iRet;
    }

所以当前发到生产环境的版本,redis服务重启的情况,业务模块是可以重连的,网络中断的话,业务模块请求redis时会卡住,直到网络恢复或者middle杀掉进程重启。

分析

封禁端口,网卡就不再处理这个端口的包,相当于网线断开了。这种情况下,客户端收不到服务器的任何回包,就会一直等待,如果没有设置超时时间,就卡住了。
redis有两个配置,一个是timeout,这个参数如果设置为0,表示服务端不会主动断开连接,非0,表示会清理空闲时间超过这个值的连接。另一个是tcp-keepalive,这个参数表示服务器定时发送ack包探测客户端是否存活。