【问题标题】:mod_wsgi not finding modules - apache, RHEL, python3.4mod_wsgi 找不到模块 - apache、RHEL、python3.4
【发布时间】:2018-12-21 08:05:17
【问题描述】:

我的 mod_wsgi 在 RHEL/Apache2.4/python3.4/Django1.11/virtualenv 上运行良好。然后,我在 virtualenv 中使用 pip 将 numpy 从 1.14.0 升级到 1.14.2,安装 pandas,并安装几个其他模块。然后我重新启动 Apache 并开始收到指示 AttributeError: 'module' object has no attribute 'arange' when trying to call numpy.arange 的服务器错误,或者在尝试调用 matplotlib.use('Agg') 等时出现类似错误。

我将 wsgi.py 替换为以下内容,它工作正常。一旦我取消注释任何 numpy 或 matplotlib 调用,它就会返回 500 错误,并且在 apache 错误日志中会显示类似于 AttributeError: 'module' object has no attribute ...

的错误
import datetime
import sys
import numpy as np
import matplotlib as mpl
import mod_wsgi

def application(env, start_response):

    #mpl.use('Agg')
    #a = np.arange(15).reshape(3, 5)
    #a = np.array([2,3,4])

    status = '200 OK'
    output = 'Hello World! This is the wsgi app generated from python!'
    output += '\n\ncurrent time is: '+str(datetime.datetime.now())
    output += '\n\nsys.executable='+sys.executable
    output += '\n\nsys.path='+str(sys.path)
    output += '\n\nsys.version=' + str(sys.version)
    output += '\n\nsys.prefix=' +  str(sys.prefix)
    output += '\n\nmod_wsgi.version='+str(mod_wsgi.version)
    output += '\n\n\nEnvironment Variables:\n\n'+'\n'.join('%s: %s' % (k, v) for (k, v) in env.items())
    output = bytes(output,'utf-8')
    response_headers = [('Content-type', 'text/plain'),
                            ('Content-Length', str(len(output)))]
    start_response(status, response_headers)
    return [output]

此 wsgi.py 的相关输出:

sys.executable=/usr/bin/python3
sys.path=['/usr/local/virtualenvs/myapp/wsgiapp', '/usr/local/virtualenvs/myapp/lib64/python34.zip', '/usr/local/virtualenvs/myapp/lib64/python3.4', '/usr/local/virtualenvs/myapp/lib64/python3.4/plat-linux', '/usr/local/virtualenvs/myapp/lib64/python3.4/lib-dynload', '/usr/lib64/python3.4', '/usr/lib/python3.4', '/usr/local/virtualenvs/myapp/lib/python3.4/site-packages']
sys.version=3.4.8 (default, Mar 23 2018, 10:04:27) 
[GCC 4.8.5 20150623 (Red Hat 4.8.5-16)]
sys.prefix=/usr/local/virtualenvs/myapp
mod_wsgi.version=(4, 5, 24)
mod_wsgi.process_group: mywsgiapp
mod_wsgi.application_group: 

Apache httpd.conf 没有改变。相关线路:

LoadModule wsgi_module "/usr/local/virtualenvs/myapp/lib64/python3.4/site-packages/mod_wsgi/server/mod_wsgi-py34.cpython-34m.so"
WSGIDaemonProcess mywsgiapp python-home=/usr/local/virtualenvs/myapp python-path=/usr/local/virtualenvs/myapp/wsgiapp
WSGIProcessGroup mywsgiapp
WSGIApplicationGroup %{GLOBAL}
WSGIScriptAlias /myapp /usr/local/virtualenvs/myapp/wsgiapp/wsgi.py process-group=mywsgiapp application-group=%{GLOBAL}

我不确定是什么导致了这个问题。我知道这通常发生在为错误版本的 python 编译 mod_wsgi 时。但这之前工作正常,一切似乎仍然配置正确:mod_wsgi 正在运行,wsgi.py 的输出表明它使用的是正确版本的 python,并且 virtualenv 的 site-packages 目录位于 python-小路。

我在主要的 python3.4 位置安装了 mod_wsgi,并尝试将 Apache LoadModule 指向该实例,但仍然得到相同的错误。

我还应该检查什么?

sys.executable 是否应该指向 virtualenv 而不是主要的 python 安装?我应该pip uninstall所有模块并重新开始吗?

另外,要安装 pandas,我必须安装 Cython,而这又需要我安装 gcc-c++ (sudo yum install gcc-c++)。这会影响什么吗?

已编辑以添加错误跟踪。我在上面的 wsgi.py 文件中取消了a = np.arange(15).reshape(3, 5) 行的注释。

来自 Apache 的 HTTP 错误页面:

内部服务器错误

服务器遇到内部错误或 配置错误,无法完成 您的要求。

请联系服务器管理员 root@localhost 通知他们此错误发生的时间, 以及您在此错误之前执行的操作。

可能会提供有关此错误的更多信息 在服务器错误日志中。

Apache 错误日志(注意我在这里发布之前已经删除了 IP 地址):

[Thu Jul 12 23:01:15.664941 2018] [wsgi:error] [pid 21490] [remote 10.x.x.x:59961] mod_wsgi (pid=21490): Exception occurred processing WSGI script '/usr/local/virtualenvs/myapp/wsgiapp/wsgi.py'.
[Thu Jul 12 23:01:15.727450 2018] [wsgi:error] [pid 21490] [remote 10.x.x.x:59961] Traceback (most recent call last):
[Thu Jul 12 23:01:15.727814 2018] [wsgi:error] [pid 21490] [remote 10.x.x.x:59961]   File "/usr/local/virtualenvs/myapp/wsgiapp/wsgi.py", line 14, in application
[Thu Jul 12 23:01:15.727831 2018] [wsgi:error] [pid 21490] [remote 10.x.x.x:59961]     a = np.arange(15).reshape(3, 5)
[Thu Jul 12 23:01:15.727865 2018] [wsgi:error] [pid 21490] [remote 10.x.x.x:59961] AttributeError: 'module' object has no attribute 'arange'

尝试显示 np.文件时出错:

[Thu Jul 12 23:25:59.196534 2018] [wsgi:error] [pid 22747] [remote 10.x.x.x:60353] mod_wsgi (pid=22747): Exception occurred processing WSGI script '/usr/local/virtualenvs/myapp/wsgiapp/wsgi.py'.
[Thu Jul 12 23:25:59.257214 2018] [wsgi:error] [pid 22747] [remote 10.x.x.x:60353] Traceback (most recent call last):
[Thu Jul 12 23:25:59.257500 2018] [wsgi:error] [pid 22747] [remote 10.x.x:60353]   File "/usr/local/virtualenvs/myapp/wsgiapp/wsgi.py", line 23, in application
[Thu Jul 12 23:25:59.257535 2018] [wsgi:error] [pid 22747] [remote 10.x.x.x:60353]     output += '\\n\\nnumpy file location='+str(np.__file__)
[Thu Jul 12 23:25:59.257569 2018] [wsgi:error] [pid 22747] [remote 10.x.x.x:60353] AttributeError: 'module' object has no attribute '__file__'

另外,仅供参考,如果我激活 virtualenv 并使用解释器,导入模块就可以正常工作:

Python 3.4.8 (default, Mar 23 2018, 10:04:27)
[GCC 4.8.5 20150623 (Red Hat 4.8.5-16)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import numpy as np
>>> np.__file__
'/usr/local/virtualenvs/myapp/lib/python3.4/site-packages/numpy/__init__.py'

从 wsgi.py 文件中打印 dir(np) 会导致:

dir(np)=['__doc__', '__loader__', '__name__', '__package__', '__path__', '__spec__']

所以它不会出错,但它不是标识符的完整列表。从 virtualenv 解释器运行 dir(np) 会导致:

['ALLOW_THREADS', 'AxisError', 'BUFSIZE', 'CLIP', 'ComplexWarning', 'DataSource', 'ERR_CALL', ..... clipped for brevity - there's a full screen of items in the list

因为它确实列出了一些标识符,所以这里是从 wsgi.py 中打印每个标识符的结果。它似乎确实从正确的路径拿起包裹。

np.__path__ =_NamespacePath(['/usr/local/virtualenvs/myapp/lib/python3.4/site-packages/numpy'])
np.doc=None
np.loader=<_frozen_importlib._NamespaceLoader object at 0x7f83b82e0c88>
np.package=numpy
np.name=numpy
np.Spec=ModuleSpec(name='numpy', loader=None, origin='namespace', submodule_search_locations=_NamespacePath(['/usr/local/virtualenvs/myapp/lib/python3.4/site-packages/numpy']))

为了确保 wsgi/python 确实找到了 numpy 包,我更改了 wsgi.py 文件以导入一个不存在的包 import foo as np,当我再次运行它时,它出现了 ImportError: No module named 'foo' 错误。所以它似乎确实在找到站点包......但只是没有完全加载它们?

【问题讨论】:

  • 包含 Python 异常的完整回溯和描述。
  • 添加了 HTTP 错误和日志
  • 将代码添加到 WSGI 脚本文件以转储出np.__file__。找出从哪里导入numpy
  • 添加了尝试打印模块文件位置的错误
  • 如果把 dir(np) 转储出去,你会得到什么?

标签: python mod-wsgi python-3.4 rhel


【解决方案1】:

有趣的事实:当 pip 安装一个新模块时,它会设置权限,以便用户能够按预期导入和使用模块,但“其他”权限允许看到模块但不能执行。因此,在 Apache 下运行的 mod_wsgi 能够导入模块,但调用任何方法都会导致错误。

解决方案:安装或更新python模块后仔细检查权限!我将所有目录设置为 755,将所有文件设置为 644,这似乎可行。或者,如评论中所述,请确保在运行 pip 之前正确设置了您的 umask。

【讨论】:

  • 您的描述听起来不正确。它与pip 无关,它受运行pip 时为您的帐户设置的umask 所控制。典型的umask0022。这将导致文件仍然可读,目录可读和可执行(可搜索)。那应该没问题。如果您将umask 更改为更具限制性的内容,以便可执行位留给其他人的目录,则只会出现问题。
猜你喜欢
  • 1970-01-01
  • 2012-05-13
  • 2021-11-30
  • 2011-05-22
  • 2013-10-19
  • 1970-01-01
  • 2017-03-16
  • 2012-05-10
相关资源
最近更新 更多