Postgres的tcp_keepalives_idle未更新AWS ELB空闲超时

时间:2019-02-26 12:49:13

标签: postgresql amazon-web-services tcp-keepalive

我在Postgres前面有一个Amazon ELB。这是由于Kubernetes相关的原因,请参见this question。我正在努力解决最长1小时的AWS ELB Idle Timeout limit的问题,以便使我的客户可以执行长时间运行的事务而不会被ELB断开连接。在这种情况下,我无法控制客户端配置,因此任何变通办法都需要在服务器端进行。

我遇到了Postgres中的tcp_keepalives_idle设置,理论上应该通过向客户端发送定期的keepalive数据包来解决此问题,从而创建活动,以便ELB认为客户端没有空闲。

我尝试通过将ELB上的idle timeout设置为2 minutes来进行测试。我将tcp_keepalives_idle设置为30秒,这将强制服务器每30秒向客户端发送一次保持活动状态。然后,我通过负载均衡器执行以下查询:psql -h elb_dns_name.com -U my_user -c "select pg_sleep(140)"。 2分钟后,ELB断开客户端连接。为什么keepalive不能传递给客户? pg_sleep是否有某些内容可能会阻止它们?如果是这样,是否有更好的方法来模拟长时间运行的查询/事务?

我担心这可能是一次深入的探讨,我可能需要带出tcpdump或类似工具。不幸的是,随着所有k8s颤动的进行,事情的解析确实变得更加复杂。因此,在走这条路线之前,我认为最好看看自己是否缺少明显的东西。如果不是这样,那么将非常感谢您提供任何有关如何最好地确定是否通过ELB将Keepalive实际发送到服务器并最终到达客户端的提示。

更新:我已就此与亚马逊联系。显然,idle被定义为不在网上传输dataData定义为具有有效负载的任何网络数据包。由于TCP保持活动没有有效负载,因此客户端和服务器保持活动被视为空闲。因此,除非有一种方法可以使服务器在其保持活动的有效负载内发送数据或以其他某种形式发送数据,否则这可能是不可能的。

1 个答案:

答案 0 :(得分:2)

Keepalive是在TCP级别(远低于PostgreSQL)上发送的,因此,如果服务器运行的是pg_sleep或其他命令,则没有任何区别。

由于托管数据库有些黑匣子,因此您可以尝试在客户端上控制行为。幸运的是PostgreSQL还提供了keepalive parameters on the client side

实验

psql 'host=elb_dns_name.com user=my_user keepalives_idle=1800' -c 'select pg_sleep(140)'