Django:Postgres连接没有关闭

ils*_*005 7 python django postgresql webfaction celery

我有一个问题,我的django应用程序累积postgres连接随着时间的推移.似乎大约每30分钟建立一个新连接并且旧连接不会关闭(参见屏幕).一段时间后,所有连接都被阻止,最大连接数设置为100.

有谁知道导致这个问题的原因是什么?

在此输入图像描述

我整合了一些之后发现了这个celery tasks.所以我很确定它与芹菜有关.

所以我尝试在每个Task使用after_return方法后手动关闭连接:

from django.db import connection

class DBTask(Task):
    abstract = True

    def after_return(self, *args, **kwargs):
        connection.close()

@task(name='example', base=DBTask)
def example_task(value):
    # do some stuff
Run Code Online (Sandbox Code Playgroud)

但这也无济于事.也许我完全错了,根本就没有关系celery.

我的数据库配置:

DATABASES = {
    'default': {
        'ENGINE': 'django.contrib.gis.db.backends.postgis',
        'NAME': 'production', 
        'USER': 'production', 
        'HOST': 'some.host', 
        'CONN_MAX_AGE': 0,
    },
}
Run Code Online (Sandbox Code Playgroud)

安装包:

  • django 1.8.9
  • pyscopg2 2.6.1
  • 芹菜3.1.20
  • django-celery 3.1.17

该应用程序部署在webfaction(也许这有帮助)

我也看过这个问题,但设置CONN_MAX_AGE: 0并没有帮助.

更新:

尝试connection.close()在每个芹菜任务结束时添加,但连接数仍在增加.

更新2:

尝试connection.close()在芹菜文件的顶部添加,但这也没有帮助.

更新3:

这是我在芹菜任务中实际使用的代码:

celery_tasks.py

@task(name='push_notifications', base=DBTask)
def push_notifications_task(user_id):
    user = CustomUser.objects.get(id=user_id)
    PusherAPI().push_notifications(user)
    connection.close()
Run Code Online (Sandbox Code Playgroud)

models.py

class PusherAPI(object):

    def push_notifications(self, user):
        from .serializers import NotificationSerializer
        self.pusher.trigger(
            'user_%s' % user.slug,
            'notifications',
            NotificationSerializer(user).data
        )
Run Code Online (Sandbox Code Playgroud)

serializers.py

class NotificationSerializer(object):

    def __init__(self, user=None):
        if user is None:
            self.user = get_current_user()
        else:
            self.user = user

    @property
    def data(self):
        # get notifications from db
        notifications = self.user.notifications.unread()
        # create the notification dict
        ...
        return note_dict
Run Code Online (Sandbox Code Playgroud)

唯一的db查询是CustomUser.objects.get(id=user_id)notifications = self.user.notifications.unread()

Dan*_*per 5

确保它实际上是未关闭的旧连接,而不是堆积的新连接,因为应用程序的某些部分无法处理负载。看看各个连接,例如SELECT * FROM pg_stat_activity;