使用Django的AppEngine应用程序无法加载

6 投票
2 回答
1324 浏览
提问于 2025-04-18 07:06

Django总是让我们的应用崩溃。部署后,应用运行得很好,但一旦初始实例重启或关闭,它常常无法启动,出现类似下面的错误:


Traceback (most recent call last):  File "/base/data/home/runtimes/python27/python27_lib/versions/1/google/appengine/runtime/wsgi.py", line 266, in Handle
    result = handler(dict(self._environ), self._StartResponse)
  File "/base/data/home/runtimes/python27/python27_lib/versions/third_party/django-1.5/django/core/handlers/wsgi.py", line 236, in call
    self.load_middleware()
  File "/base/data/home/runtimes/python27/python27_lib/versions/third_party/django-1.5/django/core/handlers/base.py", line 53, in load_middleware
    raise exceptions.ImproperlyConfigured('Error importing middleware %s: "%s"' % (mw_module, e))
ImproperlyConfigured: Error importing middleware myfolder.middleware: "No module named myfolder.middleware"

我们的文件结构大致是这样的:


|- app.yaml
|- _ _ init _ _.py
|- settings.py
|- myfolder |
|           |- _ _ init _ _.py
|           |- middleware.py
|           |- ...
|-...
|

我们的app.yaml文件内容如下:


application: XXXXX
module: app
version: master
runtime: python27
api_version: 1
threadsafe: true

handlers: - url: /api/(login|logout|passwd|master.|banners.) script: app.handler secure: always ...

builtins: - django_wsgi: on

libraries: - name: django version: 1.5

env_variables: DJANGO_SETTINGS_MODULE: 'settings'

我们的应用有两个模块,它们都表现出这种情况(配置相似)。有时候这些模块能持续运行整整一天,然后又崩溃。它们加载失败后,所有后续请求都会出现同样的错误。再部署一次总是能暂时解决这个问题。

我们使用的是普通的Django和CloudSql。在开发服务器上无法重现这个问题。部署后,两个模块中的一切都运行得很好。所有的中间件、ndb、memcache、cloudsql、taskqueue等等,包括“myfolder”里的所有模块和其他复制过来的库。

我们尝试解决这个问题的方法都没有成功:

  • 我们尝试使用appengine_config.py强制Django重新加载设置,代码是:from django.conf import settings\nsettings._target = None\n
  • 最开始我们在“myfolder”里有共享设置,并在根目录的settings.py中用“from myfolder.shared_settings import *”导入,但Django也无法加载模块myfolder.shared_settings(类似的问题)
  • 使用自定义的mysettings.py,并在app.yaml或Python中定义DJANGO_SETTINGS_MODULE

系统还没有上线,但很快就会,我们的选择越来越少。

其他类似失败配置的痕迹:


Traceback (most recent call last):
  File "/base/data/home/runtimes/python27/python27_lib/versions/1/google/appengine/runtime/wsgi.py", line 266, in Handle
    result = handler(dict(self._environ), self._StartResponse)
  File "/base/data/home/runtimes/python27/python27_lib/versions/third_party/django-1.5/django/core/handlers/wsgi.py", line 236, in __call__
    self.load_middleware()
  File "/base/data/home/runtimes/python27/python27_lib/versions/third_party/django-1.5/django/core/handlers/base.py", line 45, in load_middleware
    for middleware_path in settings.MIDDLEWARE_CLASSES:
  File "/base/data/home/runtimes/python27/python27_lib/versions/third_party/django-1.5/django/conf/__init__.py", line 53, in __getattr__
    self._setup(name)
  File "/base/data/home/runtimes/python27/python27_lib/versions/third_party/django-1.5/django/conf/__init__.py", line 48, in _setup
    self._wrapped = Settings(settings_module)
  File "/base/data/home/runtimes/python27/python27_lib/versions/third_party/django-1.5/django/conf/__init__.py", line 134, in __init__
    raise ImportError("Could not import settings '%s' (Is it on sys.path?): %s" % (self.SETTINGS_MODULE, e))
ImportError: Could not import settings 'settings' (Is it on sys.path?): No module named myfolder.settings

Traceback (most recent call last):
  File "/base/data/home/runtimes/python27/python27_lib/versions/1/google/appengine/runtime/wsgi.py", line 239, in Handle
    handler = _config_handle.add_wsgi_middleware(self._LoadHandler())
  File "/base/data/home/runtimes/python27/python27_lib/versions/1/google/appengine/api/lib_config.py", line 353, in __getattr__
    self._update_configs()
  File "/base/data/home/runtimes/python27/python27_lib/versions/1/google/appengine/api/lib_config.py", line 289, in _update_configs
    self._registry.initialize()
  File "/base/data/home/runtimes/python27/python27_lib/versions/1/google/appengine/api/lib_config.py", line 164, in initialize
    import_func(self._modname)
  File "/base/data/home/apps/s~blue-myapp/app:master.375531077560785947/appengine_config.py", line 17, in 
    settings._target = None
  File "/base/data/home/runtimes/python27/python27_lib/versions/third_party/django-1.5/django/utils/functional.py", line 227, in __setattr__
    self._setup()
  File "/base/data/home/runtimes/python27/python27_lib/versions/third_party/django-1.5/django/conf/__init__.py", line 48, in _setup
    self._wrapped = Settings(settings_module)
  File "/base/data/home/runtimes/python27/python27_lib/versions/third_party/django-1.5/django/conf/__init__.py", line 134, in __init__
    raise ImportError("Could not import settings '%s' (Is it on sys.path?): %s" % (self.SETTINGS_MODULE, e))
ImportError: Could not import settings 'settings' (Is it on sys.path?): No module named myfolder.settings

这是我们当前的appengine_config.py:


import sys
import logging

logging.debug(",\n".join(sys.path))

# Since Google App Engine's webapp framework uses Django templates, Django will half-initialize when webapp is loaded.
# This causes the initialization of the rest of Django's setting to be skipped. If you are getting this error, you need
# to explicitly force Django to reload your settings:

from django.conf import settings
settings._target = None

从appengine_config.py记录sys.path时,成功启动实例和失败启动实例之间没有变化(当然,XXXXXXXXXXX那部分除外):


/base/data/home/apps/s~blue-persomi/app:master.3759720XXXXXXXXXXX,
/base/data/home/runtimes/python27/python27_dist/lib/python27.zip,
/base/data/home/runtimes/python27/python27_dist/lib/python2.7,
/base/data/home/runtimes/python27/python27_dist/lib/python2.7/plat-linux2,
/base/data/home/runtimes/python27/python27_dist/lib/python2.7/lib-tk,
/base/data/home/runtimes/python27/python27_dist/lib/python2.7/lib-old,
/base/data/home/runtimes/python27/python27_dist/lib/python2.7/lib-dynload,
/base/data/home/runtimes/python27/python27_dist/lib/python2.7/site-packages,
/base/data/home/runtimes/python27/python27_lib/versions/1,
/base/data/home/runtimes/python27/python27_lib/versions/third_party/MySQLdb-1.2.4b4,
/base/data/home/runtimes/python27/python27_lib/versions/third_party/django-1.5,
/base/data/home/runtimes/python27/python27_lib/versions/third_party/protorpc-1.0,
/base/data/home/runtimes/python27/python27_lib/versions/third_party/webapp2-2.5.2,
/base/data/home/runtimes/python27/python27_lib/versions/third_party/webob-1.1.1,
/base/data/home/runtimes/python27/python27_lib/versions/third_party/yaml-3.10

2 个回答

0

在你的 app.yaml 文件中添加以下几行:

libraries:
- name: MySQLdb
version: "latest"

具体的说明可以在这里找到:
https://cloud.google.com/appengine/docs/python/cloud-sql/

理想情况下,这些内容应该在 GCM DJANGO 的指南中有说明。这样我就能节省很多时间了。

Praveen

2

看起来这是个路径相关的问题,就像大家在你提问的评论里提到的那样。

一个可能的简单解决办法是手动把所有东西都加到你的路径里 - 可以看看这里的最佳答案:如何在 Google App Engine 中导入模块? 至少,这样可以帮助你把问题缩小到路径相关的范围。

文档里是这么说的:https://developers.google.com/appengine/docs/python/

Python 模块的包含路径包括你应用的根目录(也就是包含 app.yaml 文件的目录)。你在应用根目录下创建的模块可以通过根目录的路径来访问。别忘了在子目录里创建 init.py 文件,这样 Python 才会把子目录识别为包。

所以根据我看到的,因为你提问中的所有内容都在 app.yaml 文件的同级或下级,路径应该已经是正确的。

  1. 仔细检查一下你的 __init__.py 文件是否都在正确的位置,并且拼写正确。
  2. 尝试删除所有的 *.pyc 文件,然后让它们重新生成。
  3. 尝试从容器的文件夹名称 FOLDER_CONTAINING_YAML.myfolder.middleware 中导入。

撰写回答