Django+Postgres FATAL:抱歉,已经有太多客户了

gla*_*oui 5 python django postgresql

我不时收到“致命:抱歉,已经有太多客户”,因为我在 Postgres 中有很多空闲连接,我无法理解它们来自哪里或如何阻止它们。

起初我CONN_MAX_AGE在 Django 中尝试了设置,但它似乎没有效果。

我也在idle_in_transaction_session_timeoutPostgres 中设置为 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)
Run Code Online (Sandbox Code Playgroud)
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)
Run Code Online (Sandbox Code Playgroud)

我知道 Django 为每个线程维护一个连接,但是(如果我能相信那个片段)我只有一个:

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
>>> 
Run Code Online (Sandbox Code Playgroud)

那么,为什么当我列出到我的数据库的连接(运行于10.100.59.225)时,我会看到这么多 ESTABLISHED 连接?

root@omaha-server-public-565447b47c-c2nqh:/usr/src/app# netstat -natup | grep  10.100.59.225 | wc -l
89
Run Code Online (Sandbox Code Playgroud)

我是 Django、Python 和 Postgres 的新手,所以我想我忽略了一些明显的东西,但我的搜索还没有带来任何有用的东西,所以我在这里尝试 :-)

版本信息:

  • Django 2.2
    • django-cacheops 4.1
    • psycopg2 2.7.3.2
  • Postgres 12.2
  • 蟒蛇 3.7.1

小智 7

这个问题已经存在了一段时间,但如果有人来到这里,这就是我面临的问题。

开发服务器(当您运行时manage.py runserver)默认是多线程的,这意味着每个请求都在创建自己的连接,并且我有一个带有池端点的服务器。我不知道这是否会对任何人有帮助,但请记住检查这种可能性,运行传递--nothreadingrunsever命令的服务器。

https://docs.djangoproject.com/en/2.1/ref/django-admin/#cmdoption-runserver-nothreading


pif*_*for 3

实际上,空闲会话中的空闲会话多于空闲事务:这看起来像是应用程序端可能存在连接泄漏。PostgreSQL 对于不运行任何事务的空闲会话没有超时。PostgreSQL 端的一个可能的解决方法是安排一个作业来终止这些空闲会话:请参阅空闲 PostgreSQL 连接是否有超时?