解密psycopg2的特例:OperationalError

时间:2016-06-26 07:13:50

标签: django postgresql error-handling psycopg2 django-middleware

我有一个带有postgresql后端的Django Web应用程序,用户会聚集并互相发送消息。这些消息可以上调或下调。如果有任何滥用行为,那么有大量弃用者的人会得到" ghost banned" (在我的网站上称为地狱禁令)。

为了做到这一点,我有一个简单的中间件来检查用户是否被禁止使用:

import os
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "myproject.settings")
from myapp.models import HellBanList

class HellBannedMiddleware(object):

    def process_request(self, request):
        if request.user.is_authenticated():
            request.user_banned = HellBanList.objects.filter(condemned=request.user).exists()
        else:
            request.user_banned = 0

根据中间件返回的内容,我在网站上采取了某些行动。

我使用newrelic来监控我的应用。间歇性地,我看到一个错误突然出现。我需要帮助来解释这个以及我可以采取哪些步骤来处理它。它如下:

psycopg2:OperationalError

/myproject.middleware.HellBanned:HellBannedMiddleware.process_request

Error message

psycopg2:OperationalError: could not translate host name "mywebapp.cloudapp.net" to address: Name or service not known 

完整堆栈跟踪如下:

Stack trace
Traceback (most recent call last):
File "/home/myuser/.virtualenvs/myenv/bin/gunicorn", line 11, in <module>
File "/home/myuser/.virtualenvs/myenv/local/lib/python2.7/site-packages/gunicorn/app/wsgiapp.py", line 74, in run
File "/home/myuser/.virtualenvs/myenv/local/lib/python2.7/site-packages/gunicorn/app/base.py", line 189, in run
File "/home/myuser/.virtualenvs/myenv/local/lib/python2.7/site-packages/gunicorn/app/base.py", line 72, in run
File "/home/myuser/.virtualenvs/myenv/local/lib/python2.7/site-packages/gunicorn/arbiter.py", line 181, in run
File "/home/myuser/.virtualenvs/myenv/local/lib/python2.7/site-packages/gunicorn/arbiter.py", line 477, in manage_workers
File "/home/myuser/.virtualenvs/myenv/local/lib/python2.7/site-packages/gunicorn/arbiter.py", line 540, in spawn_workers
File "/home/myuser/.virtualenvs/myenv/local/lib/python2.7/site-packages/gunicorn/arbiter.py", line 507, in spawn_worker
File "/home/myuser/.virtualenvs/myenv/local/lib/python2.7/site-packages/gunicorn/workers/base.py", line 124, in init_process
File "/home/myuser/.virtualenvs/myenv/local/lib/python2.7/site-packages/gunicorn/workers/sync.py", line 119, in run
File "/home/myuser/.virtualenvs/myenv/local/lib/python2.7/site-packages/gunicorn/workers/sync.py", line 66, in run_for_one
File "/home/myuser/.virtualenvs/myenv/local/lib/python2.7/site-packages/gunicorn/workers/sync.py", line 30, in accept
File "/home/myuser/.virtualenvs/myenv/local/lib/python2.7/site-packages/gunicorn/workers/sync.py", line 130, in handle
File "/home/myuser/.virtualenvs/myenv/local/lib/python2.7/site-packages/gunicorn/workers/sync.py", line 176, in handle_request
File "/home/myuser/.virtualenvs/myenv/local/lib/python2.7/site-packages/newrelic-2.56.0.42/newrelic/api/web_transaction.py", line 704, in __iter__
File "/home/myuser/.virtualenvs/myenv/local/lib/python2.7/site-packages/newrelic-2.56.0.42/newrelic/api/web_transaction.py", line 1080, in __call__
File "/home/myuser/.virtualenvs/myenv/local/lib/python2.7/site-packages/django/core/handlers/wsgi.py", line 255, in __call__
File "/home/myuser/.virtualenvs/myenv/local/lib/python2.7/site-packages/django/core/handlers/base.py", line 92, in get_response
File "/home/myuser/.virtualenvs/myenv/local/lib/python2.7/site-packages/newrelic-2.56.0.42/newrelic/hooks/framework_django.py", line 228, in wrapper
File "/home/myuser/myfolder/myproject/middleware/HellBanned.py", line 8, in process_request
File "/home/myuser/.virtualenvs/myenv/local/lib/python2.7/site-packages/django/utils/functional.py", line 202, in inner
File "/home/myuser/.virtualenvs/myenv/local/lib/python2.7/site-packages/django/utils/functional.py", line 268, in _setup
File "/home/myuser/.virtualenvs/myenv/local/lib/python2.7/site-packages/django/contrib/auth/middleware.py", line 18, in <lambda>
File "/home/myuser/.virtualenvs/myenv/local/lib/python2.7/site-packages/django/contrib/auth/middleware.py", line 10, in get_user
File "/home/myuser/.virtualenvs/myenv/local/lib/python2.7/site-packages/django/contrib/auth/__init__.py", line 134, in get_user
File "/home/myuser/.virtualenvs/myenv/local/lib/python2.7/site-packages/django/contrib/sessions/backends/base.py", line 46, in __getitem__
File "/home/myuser/.virtualenvs/myenv/local/lib/python2.7/site-packages/django/contrib/sessions/backends/base.py", line 168, in _get_session
File "/home/myuser/.virtualenvs/myenv/local/lib/python2.7/site-packages/user_sessions/backends/db.py", line 32, in load
File "/home/myuser/.virtualenvs/myenv/local/lib/python2.7/site-packages/django/db/models/manager.py", line 143, in get
File "/home/myuser/.virtualenvs/myenv/local/lib/python2.7/site-packages/django/db/models/query.py", line 382, in get
File "/home/myuser/.virtualenvs/myenv/local/lib/python2.7/site-packages/django/db/models/query.py", line 90, in __len__
File "/home/myuser/.virtualenvs/myenv/local/lib/python2.7/site-packages/django/db/models/query.py", line 301, in iterator
File "/home/myuser/.virtualenvs/myenv/local/lib/python2.7/site-packages/django/db/models/sql/compiler.py", line 775, in results_iter
File "/home/myuser/.virtualenvs/myenv/local/lib/python2.7/site-packages/django/db/models/sql/compiler.py", line 839, in execute_sql
File "/home/myuser/.virtualenvs/myenv/local/lib/python2.7/site-packages/django/db/backends/__init__.py", line 326, in cursor
File "/home/myuser/.virtualenvs/myenv/local/lib/python2.7/site-packages/django/db/backends/postgresql_psycopg2/base.py", line 182, in _cursor
File "/home/myuser/.virtualenvs/myenv/local/lib/python2.7/site-packages/newrelic-2.56.0.42/newrelic/hooks/database_dbapi2.py", line 102, in __call__
File "/home/myuser/.virtualenvs/myenv/local/lib/python2.7/site-packages/psycopg2/__init__.py", line 164, in connect

如果你仔细观察,我的地狱禁止中间件的第8行就出现了错误,恰好是这样:if request.user.is_authenticated():

这个错误像我说的那样断断续续地突然出现。上次我看到一串这样的错误是在导致我的网站崩溃的disk full错误后几个小时,虽然我已经看到它也会弹出。

任何人都可以了解一下这是什么,以及如何处理遇到此问题的不幸用户的错误?提前谢谢。

1 个答案:

答案 0 :(得分:1)

背景

似乎您在mywebapp.cloudapp.net上托管了一个postgresql数据库,并向公众开放了它的端口(5432)。这不是最好的做法。通常,出于安全原因,您应该仅在专用网络IP上公开数据库。其次,连接到远程位置的数据库意味着您要为每个查询添加20-30毫秒到几百毫秒的任何内容。如果您获取大量数据,延迟可能会在几秒钟内测量。

更糟糕的是,您正在使用服务器的FQDN而不是它的IP地址。这意味着每个请求还涉及DNS解析。除非DNS请求在本地缓存,否则可能是另外20-30毫秒的开销。你也遇到了刚刚遇到的问题!

临时解决方案:

为避免因DNS解析问题导致您的网站失败,请找到服务器的IP地址,并在django settings.py中使用它而不是主机名。