我注意到当我的数据库关闭时,对我的Django应用程序的查询会给出超时,而不是立即向客户端返回500。
跟踪问题我将config中的数据库connect_timeout设置为5s(explained here)并且日志上的异常显得更快但是在打印异常后,客户端直到30多天才收到结果。
<center><span style="padding-bottom: 4px; display: inline-block;">
<button onclick="buyside()">Swimming</button>
<button onclick="sellside()">Gymnastics</button>
<button onclick="clearFilters()">Clear Filters</button>
</span></center>
调试PDB发生的事情我发现问题出现在 django.utils.log AdminEmailHandler 中,当它尝试生成异常邮件时。
要生成邮件,它会调用 django.views.debug ExceptionReporter.get_traceback_text(),它会查找回溯中的所有帧,然后查找每个帧上的所有变量,其中一个变量是触发异常的 queryset 。
生成错误电子邮件会对生成数据库连接超时的 queryset 进行多次访问,从而产生更多数据库超时,因此对客户端的错误响应需要很长时间。
避免此问题的最佳方法是什么?
答案 0 :(得分: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)
并在settings.py
中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'
},
}
}
我还将数据库连接超时设置为1秒,我不希望在数据库无法访问的情况下将请求排队,这可能会导致连接返回时负载非常高,可以获取服务器下来。