3

スクリーン キャプチャ用の小さな API を作成しました。これは、subprocess.Popen を使用してキャプチャ リクエストを CasperJS に渡すフラスコ アプリです。

Mac での開発中、および Ubuntu 13.04 である本番サーバーのシェルでサーバーを実行すると、すべてがうまく機能します。

ただし、supervisord を使用してサーバーを管理すると、サブプロセス呼び出しで、CasperJS が PhantomJS を見つけられない (Casper は Phantom で実行される) というエラーが返されます。

スローされるエラーは次のとおりです。

Fatal: [Errno 2] そのようなファイルまたはディレクトリはありません。ファントムjsをインストールしましたか?

コードはすべてオープンソースです。

サブプロセス呼び出しは次のとおりです。

https://github.com/pwalsh/moment/blob/master/moment/models.py#L215

サーバーのスーパーバイザー conf ファイルは次のとおりです (実際のファイルは Fabric で生成しますが、明確なはずです)。

https://github.com/pwalsh/moment/blob/master/fabfile/templates.py#L56

システムには、root とアプリのユーザーの 2 人のユーザーしかいません。これらのユーザーのいずれかとしてマシンにログオンすると、開発サーバーを正常に実行でき、PhantomJS と CasperJS を正常に実行できます。

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 サブプロセスにデータを送信するコード。これはクラスのメソッドです。完全なコードは次のとおりです。

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

ノート:

  • 「瞬間」と呼ばれる仮想環境で、「瞬間」と呼ばれるユーザーの下で実行しています。
  • エラーは casper_output 変数にあります。最初の 3 つの警告は、サブプロセスを開始したときにログに記録した警告です。
  • これらの警告はルートによって発生していることに注意してください-「瞬間」によって発生することを期待していました。
4

1 に答える 1

0

(調査が必要な理由により) ユーザーは元のmomentユーザーから にエスカレートしましたがroot、これは、root としてシェルにログインしたときにプロセスに環境が存在することを意味するものではありません。

可能性として、あなたのパスは で設定されたパスのみであり、それがsupervisord.confphantomjs が存在しないように見える理由です。

ユーザーの一部のデータベースでは、環境が検索されません。代わりに、明示的に値を設定する (スクリプトを使用するなど) か、生成プロセスからの継承によって構築されます。この場合、スーパーバイザーから継承しているため、スーパーバイザーが持っていた環境を取得します。スーパーバイザーが cron などで実行された場合、その環境は空になります。

スーパーバイザーに関するベスト プラクティスは、環境を正しくセットアップするラッパー スクリプトを使用してスーパーバイザーを実行するか、supervisord.conf. 多くのスクリプトで使用されるファイルに共通の環境フィックスアップのセットがない限り (virtualenv 内で実行する場合など)、通常は後者をお勧めします。

于 2013-08-19T14:20:32.340 に答える