代码之家  ›  专栏  ›  技术社区  ›  Martin Thoma

Django的CONN_MAX_AGE何时被检查/使用?

  •  0
  • Martin Thoma  · 技术社区  · 2 月前

    最近,我的Django+Celery应用程序与Heroku上的Postgres数据库之间出现了“连接太多”的问题。

    dyno重启可能是问题所在吗?这个想法是dyno重启会断开连接,但Postgres会保留它们。

    设置 CONN_MAX_AGE 似乎已经解决了这个问题,但我不确定。

    现在的问题是: 怎么办 CONN_MAX_AGE 工作?

    (1) Django是否主动检查连接的年龄,并在连接太旧时关闭并重新启动它

    (2) 是 CONN_MAX_AGE 连接本身的参数,以便postgres在此之后自动关闭连接?

    1 回复  |  直到 2 月前
        1
  •  1
  •   willeM_ Van Onsem    2 月前

    Django是否主动检查连接的年龄,并在连接太旧时关闭并重新启动。

    Django每次打开连接时, set the time when it has to close the connection [GitHub] :

    class BaseDatabaseWrapper:
        # …
        @async_unsafe
        def connect(self):
            # …
            max_age = self.settings_dict["CONN_MAX_AGE"]
            self.close_at = None if max_age is None else time.monotonic() + max_age

    Django会,当一个名为 .close_if_unusable_or_obsolete() 被称为, close the connection [GitHub] :

    class BaseDatabaseWrapper:
        # …
        def close_if_unusable_or_obsolete(self):
            # …
            if self.connection is not None:
                # …
                if self.close_at is not None and time.monotonic() >= self.close_at:
                    self.close()
                    return

    您可以自己调用该方法来“回收”连接。但默认情况下,当请求 开始 当一个请求 末端 确实是Django registers this on two signals [GitHub] :

    def
    close_old_connections(**kwargs):
        for conn in connections.all(initialized_only=True):
            conn.close_if_unusable_or_obsolete()
    
    
    signals.request_started.connect(close_old_connections)
    signals.request_finished.connect(close_old_connections)

    因此,在请求触发之前,它将回收连接,并且在请求触发之后,回收具有不可恢复错误或过时错误的连接。在请求过程中回收这些可能不是一个好主意,因为连接可能是有状态的。