为什么在 docker (ubuntu:18.04) 中运行长时间运行的 postgres 查询需要 `psycopg2.connect(...)` 中的 `keepalives` 参数?

发布于 2025-01-11 11:26:25 字数 1299 浏览 0 评论 0原文

我们刚刚过渡到使用 Docker 进行开发,并使用 ubuntu:18.04 映像。我们注意到使用 psycopg2 的查询在几分钟后失败。 这个答案使用以下 keepalives 参数解决了问题:

self.db = pg.connect(
    dbname=config.db_name,
    user=config.db_user,
    password=config.db_password,
    host=config.db_host,
    port=config.db_port,
    keepalives=1,
    keepalives_idle=30,
    keepalives_interval=10,
    keepalives_count=5
)

这也适用于我们,但是为什么这有效? psycopg2 文档 没有深入了解参数的作用,这第三个party 文档确实如此,并且 此 postgres 文档确实如此。

问题是,docker 环境与主机环境有何不同,导致需要这些非默认设置?它们也可以在标准 Ubuntu 18.04 环境中工作,但不能在 docker 中工作。我希望我们可以重新配置我们的 docker 映像,以便首先不需要这些非标准参数。


Postgres版本:x86_64-pc-linux-gnu上的PostgreSQL 13.4 (Ubuntu 13.4-1.pgdg20.04+1),由gcc编译(Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0,64位< /code>

psycopg2 版本:2.8.5

主机操作系统:Windows 10

Docker图像操作系统:Ubuntu 18:04

We just transitioned to using Docker for development and are using the ubuntu:18.04 image. We noticed that queries using psycopg2 failed after a few minutes. This answer solved the problem using the following keepalives params:

self.db = pg.connect(
    dbname=config.db_name,
    user=config.db_user,
    password=config.db_password,
    host=config.db_host,
    port=config.db_port,
    keepalives=1,
    keepalives_idle=30,
    keepalives_interval=10,
    keepalives_count=5
)

This works for us as well, but why does this work? The psycopg2 docs do not give insight into what the params do, however, this third party documentation does, and this postgres documentation does.

The question is, what is different in the docker environment vs the host environment which makes these non-default settings required? They work in a standard Ubuntu 18.04 environment too, but not in docker. I am hoping we could reconfigure our docker image so that these non-standard parameters aren't necessary in the first place.


Postgres version: PostgreSQL 13.4 (Ubuntu 13.4-1.pgdg20.04+1) on x86_64-pc-linux-gnu, compiled by gcc (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0, 64-bit

psycopg2 version: 2.8.5

Host OS: Windows 10

Docker Image OS: Ubuntu 18:04

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

冷情 2025-01-18 11:26:25

您可能正在使用 Docker 覆盖网络功能(或用于负载均衡服务的入口网络),它基于 Linux IP 虚拟服务器 (IPVS),又名 Linux 虚拟服务器。这对空闲 TCP 连接使用默认的 900 秒(15 分钟)超时。

请参阅:https://github.com/moby/moby/issues/31208

默认Linux TCP Keep-Alive 设置仅在很晚之后才开始发送数据包(如果启用的话),因此您可以选择:

  • 更改服务器或客户端上的 TCP Keep-Alive 设置
  • 更改 Docker 网络以直接使用主机网络
  • 改变你的软件以避免空闲 TCP 连接,例如为数据库配置连接池以删除空闲连接或更频繁地检查运行状况
  • 更改内核 IPVS 默认值或 TCP 默认值

You are probably using Dockers Overlay Network feature (or Ingress network for loadbalanced services), which is based on Linux IP Virtual Server (IPVS), a.k.a.Linux Virtual Server. This uses a default 900 second (15 minutes) timeout for idle TCP connections.

See: https://github.com/moby/moby/issues/31208

Default Linux TCP Keep-Alive settings only start sending packets much later (if enabled at all) and thus you are left with the options of:

  • change the TCP Keep-Alive settings on the server or client
  • change the Docker networking to use the host network directly
  • change your software to avoid idle TCP connections, e.g. configure connection pools for databases to remove idle connections or check health more often
  • change the Kernel IPVS defaults or TCP defaults
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文