最近使用redis的list做跨进程的消息队列,客户端使用的是redis-cplusplus-client.这个client库还是蛮好用的,提供了和redis命令行一致的接口,很方便。
使用过程中发现下面一个问题。
我有多个客户端连接同一数据库,client从redis中blpop数据,设置超时为5秒。按说没什么问题,客户端也不多,不会对数据库造成什么压力。但运行一段时间后,client就从redis取不到数据了。
首先想到的是,是不是数据库连接断开了。从redis和client两侧查看6379端口的tcp连接,发现确实部分client的连接没了。但是客户端竟然没有异常,还在那傻傻的blpop!看来这个第三方库还是做得不够完善。
一个解决办法是,client和redis之间不保持长连接,每次操作都重新连接。可行,但是too simple。
后来查看了一下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 0
就是用来定时向client发送tcp_ack包来探测client是否存活的。默认不探测,官方建议值为60秒。那就试试吧。
如此设置,观察一段时间后发现client和redis之间的连接一直保持着。管用!
更多我的文章,请访问:零一积流(www.it-refer.com)