偶尔有用户会遇到远程程序连接rds pg,在不做任何操作一段时间后可能中断。
其实可能是用户和rds pg之间,某些网络设备设置了会话空闲超时,会主动中断会话。
那么有什么方法能解决这个问题呢?
运维的同学可能有这方面的经验,例如使用securecrt或者其他终端连接服务器时,可以设置这些管理工具的no-op,周期性的发一些空字符过去,保证会话上有流量。
但是数据库连接怎么搞呢?
postgresql提供了tcp keep alive的参数可供用户设置。
为了避免会话中断的问题, 可以通过tcp层的keepalive机制来达到传输心跳数据的目的.
方法一,设置数据库参数
postgresql支持会话级别的设置, 数据库级别的设置在$pgdata/postgresql.conf,
建议设置如下三个参数的值
解释详见本文末尾[参考1].
代码详见本文末尾[参考2].
参数解释
tcp_keepalives_idle : 定义这个tcp连接间隔多长后开始发送 第一个 tcp keepalive 包.
tcp_keepalives_interval : 定义在以上发送第一个tcp keepalive包后如果在这个时间间隔内没有收到对端的回包, 则开始发送第二个tcp keepalive包. 在这个时间内再没有回包的话则发送第三个keepalive包....直到达到tcp_keepalives_count次则broken 连接.
tcp_keepalives_count : 定义一共发送多少个tcp keepalive包, 达到这个数字后如果对端都没有回响应包, 则关闭这个连接.
另外需要注意的是, 这几个postgresql参数对postgresql数据库服务端的backend process生效.
所以如果发出第一个keepalive包后, 在tcp_keepalives_interval秒内有客户端回包, 则又回到tcp_keepalives_idle计数(注意此时计数是tcp_keepalives_idle 减去 tcp_keepalives_interval 秒).
例如 :
client (172.16.3.33) :
查找数据库端对应的process id.
server (172.16.3.150) :
在数据库端查看keepalive timer
在客户端查看keepalive timer
继承了操作系统的keepalive设置
通过tcpdump可以观察间隔一定的时间, 会发出keepalive包.
方法二、设置操作系统级的参数:
设置client服务器系统级的keepalive, 然后重新连接到数据库, 看看客户端的keepalive timer会不会发生变化
系统层设置的keepalive已经生效了.
.1.
通过tcpdump观察keepalive包, 也可以将这些包抓下来通过wireshark查看.
每个sock会话, 每隔13秒, 数据库服务端会发送心跳包.
.2.
由于每个tcp会话都需要1个计时器, 所以如果连接数很多, 开启keepalive也是比较耗费资源的.
可以使用setsockopt关闭该会话keepalive的功能. 下一篇blog介绍如何禁用keepalive.
.3.
如果tcp_keepalives_idle小于tcp_keepalives_interval, 那么间隔多长时间发1个心跳包呢?
例如tcp_keepalives_idle=2, tcp_keepalives_interval=10.
答案是10, 因为检查计时需要10秒.
.2. /usr/share/doc/kernel/documentation/networking/ip-sysctl.txt
.3. src/backend/libpq/pqcomm.c
.4. man netstat
.5. man 7 tcp
.6. netstat core :
以下内容转载自 :
<a href="http://vzkernel.blogspot.tw/2012/09/description-of-netstat-timers.html">http://vzkernel.blogspot.tw/2012/09/description-of-netstat-timers.html</a>