亚马逊 + Django 每 12 小时出现 [Errno 5] 输入/输出错误

12

我最近为部署我的Django项目设置并部署了一个Amazon EC2实例。

当我通过浏览器与我的应用程序交互时,浏览器中出现了此错误:

errno 5 input/output error django

在此输入图片描述

这个错误指向了我的应用程序中的某个函数。

Environment:

Request Method: GET
Request URL: http://localhost:8000/accounts/profile/

Django Version: 1.9
Python Version: 3.4.3
Installed Applications:
['django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'crispy_forms',
 'django_extensions',
 'storages',
 'userprofile']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware']



Traceback:

File "/home/ubuntu/.virtualenvs/nrb_dev/lib/python3.4/site-packages/django/core/handlers/base.py" in get_response
  149.                     response = self.process_exception_by_middleware(e, request)

File "/home/ubuntu/.virtualenvs/nrb_dev/lib/python3.4/site-packages/django/core/handlers/base.py" in get_response
  147.                     response = wrapped_callback(request, *callback_args, **callback_kwargs)

File "/home/ubuntu/.virtualenvs/nrb_dev/lib/python3.4/site-packages/django/views/generic/base.py" in view
  68.             return self.dispatch(request, *args, **kwargs)

File "/home/ubuntu/.virtualenvs/nrb_dev/lib/python3.4/site-packages/django/utils/decorators.py" in _wrapper
  67.             return bound_func(*args, **kwargs)

File "/home/ubuntu/.virtualenvs/nrb_dev/lib/python3.4/site-packages/django/contrib/auth/decorators.py" in _wrapped_view
  23.                 return view_func(request, *args, **kwargs)

File "/home/ubuntu/.virtualenvs/nrb_dev/lib/python3.4/site-packages/django/utils/decorators.py" in bound_func
  63.                 return func.__get__(self, type(self))(*args2, **kwargs2)

File "/home/ubuntu/workspace/neurorehabilitation-system/userprofile/mixins.py" in dispatch
  7.         return super(LoginRequiredMixin, self).dispatch(request, *args, **kwargs)

File "/home/ubuntu/.virtualenvs/nrb_dev/lib/python3.4/site-packages/django/views/generic/base.py" in dispatch
  88.         return handler(request, *args, **kwargs)

File "/home/ubuntu/.virtualenvs/nrb_dev/lib/python3.4/site-packages/django/views/generic/base.py" in get
  157.         context = self.get_context_data(**kwargs)

File "/home/ubuntu/workspace/neurorehabilitation-system/userprofile/views.py" in get_context_data
  50.             print (user.is_physiotherapist)

Exception Type: OSError at /accounts/profile/
Exception Value: [Errno 5] Input/output error

第50行结尾引用了一个get_context_data()函数,该函数在继承自TemplateView类的基于类的视图中。

但是,在我的控制台中,服务器要求重新启动,当我这样做时,错误以神奇的方式解决了...

我搜索了这个错误,并发现了这个报告:https://code.djangoproject.com/ticket/23284

这个报告与我的错误非常相似...

此外,昨天我遇到了这个错误,我重新启动了服务器,今天我又出现了这个错误。

EC2基础设施与Django有什么问题(我认为不会),还是问题更多地出现在我的应用程序方面?

我不认为我的应用程序中的get_context_data()函数是问题的原因...

3个回答

19

我一直在探索,我必须说这个错误的起源在我的代码中

我有两个新手错误:

  1. print 生产环境中的句子

在我上面提出的问题的回溯中,我在我的get_context_data()函数中有一个print语句,如下所示:

File "/home/ubuntu/workspace/neurorehabilitation-system/userprofile/views.py" in get_context_data
  50.             print (user.is_physiotherapist)

每次执行这个打印语句时,进程会尝试写入到我的Amazon EC2实例的stdout文件中。

我删除了该行中的打印语句,并通过git将更改检索到生产服务器,并重新启动gunicorn服务器,一切都完美地运行。

  1. 在生产环境中,我设置了DEBUG=True

我有以下设置文件:

settings/
    base.py # --- without DEBUG
    development.py # --- DEBUG=True
    testing.py # --- DEBUG=True
    production.py # --- DEBUG=False
    staging.py # --- DEBUG=False  

所有文件(development.py、testing.py、production.py、staging.py)都继承自base.py
但我不知道如何在我的EC2实例中执行production.py,它继承自base.py并将DEBUG覆盖为False。
我一直在探索,其中一种可能是根据运行应用程序的主机名更改它们的值(True或False),就像此帖子所示
在我的情况下,这是我的主机名的值。
(nrb_dev)ubuntu@ip-172-31-27-249:~$ python
Python 3.4.3 (default, Oct 14 2015, 20:28:29) 
[GCC 4.8.4] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import socket
>>> a=socket.gethostname()
>>> a
'ip-172-31-27-249'
>>> 
>>> if a != 'ip-172-31-27-249':
...     DEBUG = print ('Caleno juiciocito')
... 
>>> DEBUG
True
>>> 

这意味着将以下内容添加到我的base.py文件中:
import socket

if socket.gethostname() == 'ip-172-31-27-249':
    DEBUG = False
else:
    DEBUG = True

尽管我在代码中硬编码生产服务器的主机名,这意味着当我们想要在其他主机上部署我的项目时需要手动修改该点后面的内容。虽然它能够正常工作,但这是最佳实践吗?
我认为最适合的替代方案是修复我的DJANGO_SETTINGS_MODULE环境变量的值。
在我的特定情况下,我正在使用virtualenvwrapper,并且有两个虚拟环境:
* nrb_dev 用于开发环境 * nrb_test 用于测试环境
我有一些钩子,在虚拟环境被激活时会自动运行。
在nrb_dev中的$VIRTUAL_ENV/bin/postactivate文件中,我有以下内容:
export DJANGO_SETTINGS_MODULE="neurorehabilitation.settings.development"

同样地,在nrb_test中的$VIRTUAL_ENV/bin/postactivate中,我有以下内容:
export DJANGO_SETTINGS_MODULE="neurorehabilitation.settings.testing"

这意味着在我的Amazon EC2生产机器上,我应该更改$VIRTUAL_ENV/bin/postactivate中的钩子,以选择以下方式的settings/production.py:
export DJANGO_SETTINGS_MODULE="neurorehabilitation.settings.production"

为了测试效果和临时使用,我在我的settings/production.py文件中打印出了DEBUG的值。

from .base import *

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = False
print (DEBUG) # just for now.

当我启动gunicorn守护进程服务器时,我可以看到DEBUG值被设置为False

(注:该段内容原文已为英文,此处直接翻译即可)
(nrb_dev)ubuntu@ip-172-31-27-249:~/workspace/neurorehabilitation-system$ gunicorn -c neurorehabilitation/gunicorn_config.py neurorehabilitation.wsgi 
[2016-01-08 00:26:15 +0000] [6691] [INFO] Starting gunicorn 19.4.5
[2016-01-08 00:26:15 +0000] [6691] [INFO] Listening at: http://127.0.0.1:8000 (6691)
[2016-01-08 00:26:15 +0000] [6691] [INFO] Using worker: sync
[2016-01-08 00:26:15 +0000] [6694] [INFO] Booting worker with pid: 6694
False
^C[2016-01-08 00:26:19 +0000] [6691] [INFO] Handling signal: int

附加说明

我可以探索Django 日志功能 来记录应用程序的事件和其他内容。

我应该探索supervisor服务,以更好地管理生产中gunicorn进程。

其他supervisor资源:

在Ubuntu中安装和管理supervisor的方法

使用Nginx、Gunicorn、virtualenv、supervisor和PostgreSQL设置Django


我在这里留下评论,为那些在Django中遇到error no 5 input/output error错误的人提供帮助。我正在从django向FCM发出POST请求,并在获得响应时打印响应。这在本地上运行良好,因此部署到开发服务器上。但是只有当我的SSH终端打开时,它才能在开发环境中正常工作,并且在关闭SSH终端时会出现上述错误。因此,我删除了打印语句后解决了此问题,它神奇地开始工作了。 - Abhi

1

这个问题可能的原因和建议。

原因:

  1. 循环引用
  2. 硬盘坏道错误
  3. 复杂的进程、用户、网络、权限等引发混合错误

建议:

  1. 使用日志记录代替打印,这是最好的方法!!!
  2. 将IO重定向到文件或null:python test.py > test.log 2>&1 &python test.py > /dev/null 2>&1 &

0

文件 "./my_api/to/Credit.py",第17行,在get_credit_from_response函数中

print xml_response

堆栈跟踪已经很清楚了。您有一个名为get_credit_from_response的函数 - 在其中发生了I/O错误。它可能每6/12小时计划一次并导致问题。请仔细检查您的代码。


感谢阅读并检查该票据,但这不是我的问题。我已经编辑了我的问题以添加更多关于我的疑问的细节,但当我在这里阅读您的回复时,我明白所报告的票证是用户应用程序错误的一个案例,而不是Amazon EC2与Django有关的错误。我是对的吗?我无法截取与我特定错误相关的屏幕截图,但这确实涉及到我的应用程序的一个功能...虽然如下所述,我重新启动了我的服务器,并解决了所有问题...我还将继续在EC2中部署我的应用程序以详细了解其行为。 :D - bgarcial
我已经修改了我的问题,因为今天错误再次出现。任何指导都将不胜感激。 - bgarcial
我一直在探索,本文描述了一个相关的情况(不是同样的错误或回溯),但这个人也说他重新启动了服务器,问题就解决了。在这个线程中,有一个答案提到了检查自动缩放部分和健康检查计划(可能对他们的情况有用),尽管我认为我的项目部署太小了,不适合这种方法。 - bgarcial

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接