最近使用redis的list作跨进程的消息队列,客户端使用的是redis-cplusplus-client.这个client库仍是蛮好用的,提供了和redis命令行一致的接口,很方便。git
使用过程当中发现下面一个问题。github
我有多个客户端链接同一数据库,client从redis中blpop数据,设置超时爲5秒。按说没什麽问题,客户端也很少,不会对数据库形成什麽压力。但运行一段时间后,client就从redis取不到数据了。redis
首先想到的是,是否是数据库链接断开了。从redis和client两侧查看6379端口的tcp链接,发现确实部分client的链接没了。可是客户端居然没有异常,还在那傻傻的blpop!看来这个第三方库仍是作得不够完善。数据库
一个解决办法是,client和redis之间不保持长链接,每次操做都从新链接。可行,可是too simple。tcp
后来查看了一下redis的配置文件,发现有一个tcp-keepalive的选项。
# TCP keepalive.
#
# If non-zero, use SO_KEEPALIVE to send TCP ACKs to clients in absence
# of communication. This is useful for two reasons:
#
# 1) Detect dead peers.
# 2) Take the connection alive from the point of view of network
# equipment in the middle.
#
# On Linux, the specified value (in seconds) is the period used to send ACKs.
# Note that to close the connection the double of the time is needed.
# On other kernels the period depends on the kernel configuration.
#
# A reasonable value for this option is 60 seconds.
tcp-keepalive 0th
就是用来定时向client发送tcp_ack包来探测client是否存活的。默认不探测,官方建议值爲60秒。那就试试吧。命令行
如此设置,观察一段时间后发现client和redis之间的链接一直保持着。