【发布时间】:2013-08-18 20:21:38
【问题描述】:
我为屏幕捕获编写了一个小 API - 一个使用 subprocess.Popen 将捕获请求传递给 CasperJS 的烧瓶应用程序
在 Mac 上进行开发,当我在 Ubuntu 13.04 生产服务器上的 shell 中运行服务器时,一切正常。
但是,当我使用 supervisord 管理服务器时,子进程调用返回一个错误,即 CasperJS 找不到 PhantomJS(Casper 在 Phantom 上运行)。
抛出的错误是:
致命:[Errno 2] 没有这样的文件或目录;你安装了 phantomjs 吗?
代码全部开源。
这是子进程调用:
https://github.com/pwalsh/moment/blob/master/moment/models.py#L215
这是服务器的supervisor conf文件(我用Fabric生成了实际的文件,但应该很清楚):
https://github.com/pwalsh/moment/blob/master/fabfile/templates.py#L56
系统上只有两个用户 - root 和我的应用程序的用户。当我作为这两个用户登录机器时,我可以成功运行一个开发服务器,并且我可以成功运行 PhantomJS 和 CasperJS。
为什么我的 subprocess 使用 supervisord 出错?
编辑:添加代码 + 堆栈跟踪
gunicorn 服务器的Supervisord conf:
; Generated via Fabric on 2013-08-18 23:05:50.928087
; gunicorn configuration for Moment
[program:moment-gunicorn]
command=/srv/environments/moment/bin/gunicorn moment:app --bind 127.0.0.1:9000 --workers 4 --timeout 30 --access-logfile /srv/logs/moment_gunicorn_access.log --error-logfile /srv/logs/moment_gunicorn_error.log
environment=PATH="/srv/environments/moment/bin"
directory=/srv/projects/moment
user=moment
autostart=true
autorestart=true
向 CasperJS/PhantomJS 子进程发送数据的代码。它是一个类的方法,完整的code is here:
def capture(self):
filename = '{key}.{format}'.format(key=self.get_key().lstrip(self.prefix),
format=self.arguments['format'])
image = os.path.join(conf.CAPTURES_ROOT, filename)
params = [conf.CASPER, conf.CAPTURE_SCRIPT, self.arguments['url'],
image, self.arguments['viewport'], self.arguments['target']]
casper = subprocess.Popen(params, stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
casper_output, casper_errors = casper.communicate()
logging.info(casper_output)
logging.info(casper_errors)
logging.info(casper.returncode)
# Here we are relying on convention:
# If success, subprocess.returncode == 0
# This could be fragile, need to investigate.
if casper.returncode:
raise Exception(casper_errors)
else:
return image
追溯:
WARNING:root:Fatal: [Errno 2] No such file or directory; did you install phantomjs?
WARNING:root:
WARNING:root:1
ERROR:moment:Exception on /capture/ [GET]
Traceback (most recent call last):
File "/srv/environments/moment/local/lib/python2.7/site-packages/flask/app.py", line 1817, in wsgi_app
response = self.full_dispatch_request()
File "/srv/environments/moment/local/lib/python2.7/site-packages/flask/app.py", line 1477, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/srv/environments/moment/local/lib/python2.7/site-packages/flask/app.py", line 1381, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "/srv/environments/moment/local/lib/python2.7/site-packages/flask/app.py", line 1475, in full_dispatch_request
rv = self.dispatch_request()
File "/srv/environments/moment/local/lib/python2.7/site-packages/flask/app.py", line 1461, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "/srv/projects/moment/moment/views.py", line 45, in get_capture
image = capture.capture()
File "/srv/projects/moment/moment/models.py", line 229, in capture
raise Exception(casper_errors)
Exception
注意:
- 我在一个名为“moment”的虚拟环境中运行,并在一个名为“moment”的用户下运行。
- 错误在 casper_output 变量中 - 前三个警告是我在启动子进程时记录的警告
- 我注意到这些警告是由 root 提出的 - 我原以为它们会在“时刻”提出,即主管进程应该作为运行的用户
【问题讨论】:
-
在此处显示代码以及完整的回溯。问题几乎可以肯定是您的 supervisord.conf(或运行它的环境)没有设置为使 PhantomJS 可见。
-
我添加了代码+回溯,谢谢。
-
抛出异常之前记录的信息是什么?看起来它可能包含有用的信息。
-
另外,你的路径只有
"/srv/environments/moment/bin"。您要查找的可执行文件是否存储在该目录中?如果没有,那就是问题所在。 -
这是整个回溯。关于 PATH,我了解主管的“环境”配置扩展执行用户的配置。这里supervisord.org/configuration.html 说“子进程将继承用于启动supervisord 的shell 的环境变量”。就我而言,它是 root,并且 root 在 PATH 上有 /usr/bin/。
标签: python phantomjs gunicorn casperjs supervisord