【发布时间】:2023-11-20 14:46:01
【问题描述】:
我不时收到“致命:抱歉,已经有太多客户”,因为我在 Postgres 中有很多空闲连接,我不明白它们来自哪里或如何防止它们。
一开始我尝试了Django中的CONN_MAX_AGE设置,但似乎没有效果。
我还在 Postgres 中将 idle_in_transaction_session_timeout 设置为 5 分钟,但我一直看到很多空闲事务:
postgres=# select client_addr, state, count(*) from pg_stat_activity group by client_addr, state;
client_addr | state | count
---------------+--------+-------
| | 5
| active | 1
| idle | 1
172.30.12.148 | idle | 2
172.30.12.74 | idle | 89
(5 rows)
postgres=# select client_addr, state, backend_start, query_start from pg_stat_activity order by query_start ;
client_addr | state | backend_start | query_start
---------------+--------+-------------------------------+-------------------------------
| idle | 2020-03-24 20:03:16.060707+00 | 2020-03-24 20:55:17.020962+00
172.30.12.74 | idle | 2020-03-25 02:05:32.567976+00 | 2020-03-25 02:05:32.613112+00
172.30.12.74 | idle | 2020-03-25 02:05:34.926656+00 | 2020-03-25 02:05:34.945405+00
172.30.12.74 | idle | 2020-03-25 02:05:49.700201+00 | 2020-03-25 02:05:49.717165+00
[...]
172.30.12.74 | idle | 2020-03-25 04:00:51.019892+00 | 2020-03-25 04:01:22.627659+00
172.30.12.74 | idle | 2020-03-25 04:04:18.333413+00 | 2020-03-25 04:04:18.350539+00
172.30.12.74 | idle | 2020-03-25 04:04:35.157547+00 | 2020-03-25 04:05:16.746978+00
172.30.12.74 | idle | 2020-03-25 04:05:08.241291+00 | 2020-03-25 04:05:39.367247+00
172.30.12.148 | idle | 2020-03-25 04:07:02.717151+00 | 2020-03-25 04:07:02.726822+00
172.30.12.74 | idle | 2020-03-25 04:07:48.07922+00 | 2020-03-25 04:07:48.112819+00
| active | 2020-03-25 04:00:10.608213+00 | 2020-03-25 04:07:57.336091+00
| | 2020-03-24 19:40:38.624442+00 |
| | 2020-03-24 19:40:38.624876+00 |
| | 2020-03-24 19:40:38.624003+00 |
| | 2020-03-24 19:40:38.623479+00 |
| | 2020-03-24 19:40:38.62598+00 |
(99 rows)
我知道 Django 为每个线程维护一个连接,但是(如果我相信 sn-p)我只有一个:
root@omaha-server-public-565447b47c-c2nqh:/usr/src/app# python manage.py shell
Python 3.7.1 (default, Nov 16 2018, 22:26:09)
[GCC 6.3.0 20170516] on linux
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> import threading
>>> for thread in threading.enumerate(): print(thread.name)
...
MainThread
>>>
那么,为什么当我列出到我的数据库的连接(在 10.100.59.225 运行)时,我看到这么多 ESTABLISHED 连接?
root@omaha-server-public-565447b47c-c2nqh:/usr/src/app# netstat -natup | grep 10.100.59.225 | wc -l
89
我是 Django、Python 和 Postgres 的新手,所以我想我忽略了一些明显的东西,但是我的搜索还没有带来任何有用的东西,所以我在这里尝试 :-)
版本信息:
- Django 2.2
- django-cacheops 4.1
- psycopg2 2.7.3.2
- Postgres 12.2
- Python 3.7.1
【问题讨论】:
-
shell管理命令无法提供有关 Django 服务器中线程的任何信息,因为它是具有自己线程的自己的进程。 -
查看 pg_stat_activity.query(他们在空闲之前运行的最后一个查询)可能会帮助您了解他们来自哪里。
-
感谢@KlausD.,我将使用
gdb重试并使用该信息编辑我的帖子。 -
根据@jjanes 的建议,我分析了查询,结果始终是+/-。我想我把它缩小到a cached QuerySet,但我仍然不明白为什么保持连接。如果我理解正确Django's auto close mechanism 这不应该发生。从我收集的信息来看,应用程序本身没有与数据库创建直接连接,这一切都依赖于其他库(cacheops,rest_framework,...)
-
我刚刚在一个快速的 CentOS 机器上遇到了同样的问题,这是一个直接进入 PostgreSQL 10 的 Ruby gem。多个客户端运行相同的容量。我用 12 个连接(4 个核心)对其进行了测试,这是一篇关于优化主题的 PostgreSQL 文本推荐的(3x 核心数)。我的查询很简单,实际上是返回的,然后保持空闲,然后重复该过程。我有 5 个查询要求上次登录。该表是测试表的大小。这听起来像是 PostgreSQL 问题。
标签: python django postgresql