背景
va_list的bug,修改后,在开发环境验证时,发现执行redisCommand函数时,会卡住,直到进程被杀掉重启。为啥生产环境直接进入了第二次循环,没有卡住呢?
两种情况
- redis没有切过master,老的连接有时也不能用,报错
Connection reset by peer,这时会自动重连,大概一天2次这种报错,为啥连接会中断,这个还没找到原因。 - 为何我验证的情景下,请求老的连接时会卡住呢?是因为我是通过封禁redis端口的方法触发redis切换的。切换master后,分两种情况:
redis之前的master变成了slave,再次请求时,报错
server closed the connection redis,这种情况也会自动重连。如果把master的端口禁用,redis切换master后,业务模块再请求之前的连接会卡住,这种情况需要设置超时时间。
1
2
3
4
5
6iRet = 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包探测客户端是否存活。
