2016-09-22 9 views
0

私のデータベースがダウンしたときに、Djangoアプリケーションへのクエリがクライアントに即座に500を返すのではなく、タイムアウトになることに気付きました。DBにアクセスできないときにDjango AdminEmailHandlerがハングする

私はデータベースのconnect_timeoutを5秒(explained here)に設定しましたが、ログには例外がより速く表示されますが、例外を印刷した後、クライアントは結果を30秒以上受け取ることはありません。

PDBで何が起こっているのかデバッグ
OperationalError: (2003, "Can't connect to MySQL server on 'db.example.com' (4)") 

私はそれが例外のメールを生成しようとすると、問題は、django.utils.log AdminEmailHandlerであることがわかりました。

は、それがトレースバックにし、すべてのフレームを探しdjango.views.debug ExceptionReporter.get_traceback_text()を呼び出してメールを生成するには、各フレーム上のすべての変数のために、これらの変数の一つがクエリセットであります例外が発生しました。

クエリーセットに複数のアクセスを行い、DB接続のタイムアウトを生成し、より多くのDBタイムアウトを生成するため、クライアントへのエラー応答に時間がかかります。

この問題を回避するには、どのような方法が最適ですか?

答えて

0

もっと良い選択肢はありませんが、これは私が実装した解決策です。

例外を検査するカスタムAdminEmailHandlerをセットアップしました。データベースの場合、OperationalErrorは例外をスキップし、送信とエラーを代わりに行います。

import logging 

from django.utils.log import AdminEmailHandler 
from django.db.utils import OperationalError 

logger = logging.getLogger('mylogger') 

class CustomAdminEmailHandler(AdminEmailHandler): 

     # When mail is because of exception conencting to DB, avoid rendering the email, 
     # rendering email makes connections to DB making the query hang in multiple DB 
     # connection timeouts. 
     if record.exc_info: 
      exc_type, exc_value, exc_traceback = record.exc_info 
      if exc_type == OperationalError: 
       logger.error(exc_value, exc_info=False) 
       return 

     super(CustomAdminEmailHandler, self).emit(record) 

そして、私はまた、1秒にデータベース接続タイムアウトを設定している

LOGGING = { 
    'version': 1, 
    'disable_existing_loggers': False, 
    'formatters': { 
     'simple': { 
      'format': '%(asctime)s %(levelname)s %(module)s:%(funcName)s() %(message)s' 
     }, 
    }, 
    'handlers': { 
     'send_mail': { 
      'level': 'ERROR', 
      'class': 'myapp.handlers.CustomdAdminEmailHandler', 
      'include_html': False, 
     }, 
    }, 
    'loggers': { 
     'django': { 
      'handlers': ['send_mail'], 
      'level': 'INFO' 
     }, 
     'mylogger': { 
      'handlers': ['send_mail'], 
      'level': 'INFO' 
     }, 
    } 
} 

settings.pyで

は、私は、要求がデータベースにアクセスできない場合にキューイングするために、これをしたくありませんサーバーがダウンする可能性のある接続が戻ったときに非常に高い負荷がかかる可能性があります。

関連する問題