【问题标题】:gunicorn is corrupting sys.pathgunicorn 正在破坏 sys.path
【发布时间】:2018-01-16 09:48:58
【问题描述】:

我写了一个简单的python程序:

# /tmp/src/Code.py
import sys
print sys.path

# /tmp/src/Main.py
import Code

当我使用python src/Main.py 运行它时,它按预期工作:

max% cd /tmp
max% setenv PYTHONPATH src
max% python src/Main.py
['/tmp/src',
 '/tmp/src',
 '/usr/lib/python2.7',
 '/usr/lib/python2.7/plat-x86_64-linux-gnu',
 '/usr/lib/python2.7/lib-tk',
 '/usr/lib/python2.7/lib-old',
 '/usr/lib/python2.7/lib-dynload',
 '/usr/local/lib/python2.7/dist-packages',
 '/usr/lib/python2.7/dist-packages',
 '/usr/lib/python2.7/dist-packages/PILcompat',
 '/usr/lib/python2.7/dist-packages/gtk-2.0',
 '/usr/lib/python2.7/dist-packages/ubuntu-sso-client']

为了确保 sys.path 正常工作,我在工作目录中创建了一个文件:

# /tmp/Code.py
print "I never said to search CWD!!! Your Python is broken."
import sys
print sys.path

结果和上面一样,和预期的一样。

但是,当我在 gunicorn 中运行时,我得到:

max% gunicorn Main:app
2017-08-08 10:30:53 [26913] [INFO] Starting gunicorn 17.5
2017-08-08 10:30:53 [26913] [INFO] Listening at: http://127.0.0.1:8000 (26913)
2017-08-08 10:30:53 [26913] [INFO] Using worker: sync
2017-08-08 10:30:53 [26918] [INFO] Booting worker with pid: 26918
I never said to search CWD!!! Your Python is broken.
['/tmp',
 '/usr/bin',
 '/tmp/src',
 '/usr/lib/python2.7',
 '/usr/lib/python2.7/plat-x86_64-linux-gnu',
 '/usr/lib/python2.7/lib-tk',
 '/usr/lib/python2.7/lib-old',
 '/usr/lib/python2.7/lib-dynload',
 '/usr/local/lib/python2.7/dist-packages',
 '/usr/lib/python2.7/dist-packages',
 '/usr/lib/python2.7/dist-packages/PILcompat',
 '/usr/lib/python2.7/dist-packages/gtk-2.0',
 '/usr/lib/python2.7/dist-packages/ubuntu-sso-client']

gunicorn 似乎随机决定将 PWD 添加到 sys.path。 gunicorn 手册页中没有关于此的任何内容。

python 配置:

Flask==0.10.1
Jinja2==2.7.2
MarkupSafe==0.18
PAM==0.4.2
Pillow==2.3.0
Twisted-Core==13.2.0
Twisted-Web==13.2.0
Werkzeug==0.9.4
adium-theme-ubuntu==0.3.4
apt-xapian-index==0.45
argparse==1.2.1
blinker==1.3
chardet==2.0.1
colorama==0.2.5
command-not-found==0.3
debtagshw==0.1
defer==1.0.6
dirspec==13.10
duplicity==0.6.23
gevent==1.0
greenlet==0.4.2
gunicorn==17.5
html5lib==0.999
httplib2==0.8
itsdangerous==0.22
lockfile==0.8
lxml==3.3.3
oauthlib==0.6.1
oneconf==0.3.7.14.04.1
pexpect==3.1
piston-mini-client==0.7.5
pyOpenSSL==0.13
pycrypto==2.6.1
pycups==1.9.66
pygobject==3.12.0
pyinotify==0.9.4
pyserial==2.6
pysmbc==1.0.14.1
python-apt==0.9.3.5ubuntu2
python-debian==0.1.21-nmu2ubuntu2
pyxdg==0.25
reportlab==3.0
requests==2.2.1
sessioninstaller==0.0.0
simplejson==3.3.1
six==1.5.2
software-center-aptd-plugins==0.0.0
ssh-import-id==3.21
system-service==0.1.6
unity-lens-photos==1.0
urllib3==1.7.1
wheel==0.24.0
wsgiref==0.1.2
xdiagnose==3.6.3build2
zope.interface==4.0.5

我知道我可以通过搜索 realpath(p) == realpath('.') 从 sys.path 中删除 PWD,但有时我们需要 PYTHONPATH 中的 PWD。所以需要更谨慎的解决方案。理想情况下,我们会尝试找出是哪个软件引入了这个错误。可能只是 gunicorn 联机帮助页不完整?

【问题讨论】:

  • 我发现gunicorn --pythonpath srcsetenv PYTHONPATH src 效果更好。我希望 gunicorn 有实际的文档。
  • gunicorn 似乎在 PWD 前面加上 --pythonpath,然后是 PYTHONPATH。所以总是用--pythonpath $PYTHONPATH 运行 gunicorn 应该是一个通用的解决方案。这确实应该添加到手册页中。
  • 描述您如何解决问题作为问题的答案,然后批准。
  • 不,不。事实证明--pythonpath 不可靠。在 gunicorn 19.6.0 上,PWD 仍然插入到路径的前面。
  • 看来,如果您破解wsgiapp.py,如下面的回答所示,那么--pythonpath 将按预期工作。

标签: python gunicorn


【解决方案1】:

编辑/usr/lib/python2.7/dist-packages/gunicorn/app/wsgiapp.py 并更改以下行:

sys.path.insert(0, cwd)

到:

sys.path.append(cwd)

然后--pythonpath 按预期工作。

【讨论】:

  • 我们如何制作一个标准的python包来执行上面显示的编辑?让我们将我们的包称为gunicorn_pythonpath_enabler 或类似的名称。
  • 向 Gunicorn 发出拉取请求比在某些库中打包补丁更有效。
【解决方案2】:

我切换到 BaseHTTPServer,因为它的速度提高了 2 倍(我的应用程序必须有效地扩展)。

它已预装在 Python 2.7 中。

它可以流式传输: Python 2.7: streaming HTTP server supporting multiple connections on one port

并且不会与标准日志记录设置混淆: time.time() stops the server process silently when using Flask

并且不需要我破解 WSGI。

并且不需要 4 个包(gunicorn、gevent、flask、wsgi、werkzeug)。

而且代码库更加稳定。

而且更容易理解它在做什么。

用户可以只运行./app -arg 而不是/usr/bin/gunicorn 'app:build_app("-arg")'

我需要多少理由???

【讨论】:

  • 当然,BaseHTTPServer 很小,但实际上没有任何功能。你在干嘛?如果你只是想静态地提供文件,像 Nginx 这样的服务器可能会更好。
  • @Nick 我正在使用 RESTful API 和嵌入在服务器中的数据库实现多线程服务,各种类型的客户端连接到该服务器,用于提交任务、检索工作句柄、执行管理等。通过扩展效率要求。注意:SQL 对于这个应用程序来说太慢了。
  • @Nick 请更具体地说明哪些 gunicorn 功能在包中实际上是有用的。当我摆脱它时,我保存了 30 行解决方法代码,这比我必须添加的 15 行代码要多,以获取类似 Flask 的 URL 装饰器和响应代码糖。
  • 无论你喜欢哪个应用服务器,这实际上并不能回答关于 GUnicorn 的问题
  • @Charles 嗯,是的。问题是如何处理 gunicorn 的这个问题。这对我来说是最好的答案。另外,我的另一个回答得了 0 票。
猜你喜欢
  • 2021-08-07
  • 1970-01-01
  • 2016-07-02
  • 2012-06-26
  • 1970-01-01
  • 1970-01-01
  • 2011-03-15
  • 2012-08-23
  • 2014-01-04
相关资源
最近更新 更多