node之中链接redis使用的redis模块,虽然好用,可是有些地方仍是须要注意。node
npm install redisredis
redis client 行为:
一、客户端执行过程当中断网的状况
因为本来链接正常,断网后socket没法主动检测到,所以TCP进入不断的重传,ubuntu系统大概在1000秒左右返回ETIMEOUT。
因为redis客户端没有等待回复超时时间,因此会等待到TCP超时才最终致使超时。
二、重链接机制:当服务端异常断开会致使重链接,而如果客户端主动断开则不会重链接
以下两种状况表示客户端主动断开:
1)向服务端发送quit命令
2)调用客户端类的end函数
重链接选项:
max_attempts:重试次数,默认无限制
retry_max_delay:两次重链接之间有一个延迟,默认按照指数避退原则不断增长,这个数值设置延迟的最大值
connect_timeout:链接的超时时间(包括重链接),也就是若设置这个参数,达到这个值后就不会重链接(在这个时间内会按照重链接规则进行屡次尝试,直到时间用尽)
三、设置client.stream.setTimeout这种方式,对于不断向服务器发送命令的应用无效
由于sock的timeout表示空闲超时,只有在发送与接收都没有数据时才计入空闲时间,
而因为应用不断向服务端发送命令,也就是在发送上是处于忙状态,不能记录为空闲。npm
四、关于end事件
使用redisClient.quit()向服务端发送quit命令,服务端关闭链接,redis客户端可以收到end事件通知。
使用redisClient.end()函数主动关闭链接时,redis客户端不会收到end事件通知。
缘由:
redisClient.end()函数体中有一条语句
this.stream._events = {}; //将socket链接上注册的全部事件清空
因为redisClient上的事件是基于socket事件的,当socket事件清空后,redisClient自己也就没法触发任何事件了。
延伸:socket的end事件触发时机:当读取到一个EOF时触发,所以若没有注册data事件(监控数据可读),也就不会有end事件。
socket的close在被关闭时触发,所以只要不是极端的清除全部的注册事件,均可以收到该事件通知。
五、关于redisClient的命令队列与离线队列
命令队列offline_queue:
当前链接可用时客户端会将命令不断发出去,每出去一个在队列末尾添加一项,收到一个回复从队列头部删除一项。所以当应用使用多个链接时可能会出现,A链接执行set命令,B链接去查询为空,那是因为A链接上的set命令还在队列里等待redis执行。
长度查询:client.command_queue.length
离线队列offline_queue:
当前链接不可用时,客户端会将命令放置到离线队列之中,同时重链接规则尝试链接服务器,每次尝试失败都会清空离线队列。
长度查询:client.offline_queue.length
可以使用enable_offline_queue:false选项关闭该功能。
六、错误时的回调
若在执行命令中设置了回调函数,当有异常时这个回调会先被调用,而后触发error事件。ubuntu