我有一个问题,我真的不知道从哪里开始解决。也许它会敲响别人的钟声。
TLDR: Django应用程序崩溃,重启后运行但无法导入某些模块。再次重启时,一切都很好。
整个故事:
偶尔在不同的Python(2.5.x,2.6.x和2.6.x)和Django版本(分别为1.1.0,1.2.5和1.3.0)上的不同应用程序(我们现在最多三个)展示虚假的ImportErrors。例如,其中一个应用程序通过在其中抛出ImportError开始使每个请求失败:
from django.contrib.gis.maps.google import GMarker, GEvent
我们收集了strace
输出,相关的块在下面(为了简洁和保护有罪,绝对路径被DIR取代)。
stat64("DIR/django/contrib/gis/maps/google/GMarker", 0xf699ce3c) = -1 ENOENT (No such file or directory)
open("DIR/django/contrib/gis/maps/google/GMarker.so", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("DIR/django/contrib/gis/maps/google/GMarkermodule.so", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("DIR/django/contrib/gis/maps/google/GMarker.py", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("DIR/django/contrib/gis/maps/google/GMarker.pyc", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
(再一次是同样的事情s / GMarker / GEvent /)
重新启动流程后,一切运行顺利,同时运行:
python -c 'from django.contrib.gis.maps.google import GMarker'
不会产生错误。
GMarker和GEvent类实际上是在django.contrib.gis.maps.google.overlays
中定义的,并在...maps/google/__init__.py
中导入:
from django.contrib.gis.maps.google.gmap import GoogleMap, GoogleMapSet
from django.contrib.gis.maps.google.overlays import GEvent, GIcon, GMarker, GPolygon, GPolyline
from django.contrib.gis.maps.google.zoom import GoogleZoom
因此完全可以预期加载GMarker.py等。将失败。似乎Python已经忘记了__init__.py
及其命名空间。
这些应用程序的流量相对较高,可以想象(虽然不确定)它们可能已经超出了VM的限制并且几乎可以优雅地恢复。此外,至少在两种情况下,应用程序早先出现导致崩溃的问题 - 一种情况下出现SIGSEGV,另一种出现错误......其他情况。单个应用程序重新启动导致它抛出ImportErrors,另一个使它再次运行。瑕疵.py [c]?时间戳很古老。
所有这些应用程序都在wsgi-to-fastcgi服务器上运行。
到目前为止,这些应用程序中的每一个都失败了一次(在完全不同的模块中,有两个__init__.py
被遗忘的情况“但是我找不到第三个错误的ATM)所以我无法判断模块是否在某种程度上有意义。
赞赏所有指针和想法!
答案 0 :(得分:1)
实际上你的strace线没有帮助;这些访问不会导致模块被导入。
此类导入错误可能有多种原因:
如果要粘贴第二组strace线,我们会更接近解决方案吗?
对于2.我的意思是如果你有2个具有以下结构的文件
foo.py/的初始化强>的.py:
from bar import baz
bar.py/的初始化强>的.py:
import foo
def baz():
pass
snafu.py:
import bar
import foo
ok.py:
import foo
import snafu
运行python snafu.py并且你得到一个崩溃和类似的strace输出,运行python ok.py并且一切正常。
答案 1 :(得分:0)
strace输出对我来说似乎很可疑:
DIR/django/contrib/gis/...
我想知道这个DIR
部分。是否有可能使用DIR
代替$DIR
在某处错误地输入了PYTHONPATH变量?
答案 2 :(得分:0)
我建议你用try尝试包装导入...除了ImportError并添加代码做类似的事情(任何记录,而不是打印,都会这样做)
import sys
print sys.modules["django.contrib.gis.maps.google"]
print dir(sys.modules["django.contrib.gis.maps.google"])
这可以让你了解正在发生的事情。