天天看点

如何防止远程程序与RDS PG连接中断

偶尔有用户会遇到远程程序连接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>