1 回答
TA贡献1816条经验 获得超6个赞
我也遇到过类似的问题。在我们的案例中,问题是由位于客户端计算机和数据库之间的连接跟踪防火墙引起的。
这样的防火墙会跟踪 TCP 级别的连接,并且为了限制资源使用,然后会超时在它们看来长时间不活动的连接。我们在这种情况下观察到的症状与您的非常相似:在客户端,连接似乎挂起,而在服务器端,您可以看到connection reset by peer
.
防止这种情况的一种方法是确保启用TCP Keepalive,并且 Keepalive 间隔小于导致连接问题的防火墙、路由器等的超时时间。这是由libpq的连接参数控制keepalives
,keepalives_idle
,keepalives_interval
和keepalives_count
您可以在连接字符串中设置。有关这些参数的说明,请参阅手册。
keepalive
确定是否启用keepalive 功能。它默认为1
(启用),因此您可能不需要指定它。keepalives_idle
确定发送保活之前的空闲时间量。如果不指定此项,它将默认为操作系统的默认值。在 Linux 系统中,您可以通过检查来查看默认值
/proc/sys/net/ipv4/tcp_keepalive_time
- 在我的服务器中,它设置为 7200 秒,这在您的情况下太长了,因为您观察到连接在大约 1 小时后断开。您可以尝试将其设置为 2500 秒。
Linux 文档项目提供了一个有用的TCP Keepalive HOWTO文档,其中详细描述了它们的工作原理。
请注意,并非所有操作系统都支持 TCP keepalive。如果您无法启用 keepalive,这里有一些您可能需要考虑的其他选项:
如果它在您的控制之下,请重新配置正在断开连接的防火墙/路由器,以便它不会对 Postgresql 客户端连接这样做
在应用程序级别,您可能能够发送一些流量来保持数据库句柄处于活动状态 - 例如发送一个语句,例如
SELECT 1;
每小时左右。如果您的编程环境提供连接缓存(根据我收集的评论),那么这可能会很棘手。
- 1 回答
- 0 关注
- 186 浏览
添加回答
举报