[python] Flask 개발 서버를 실행하면 자체적으로 두 번 실행되는 이유는 무엇입니까?

웹 사이트 개발을 위해 Flask 를 사용 하고 있으며 개발 중에 다음 파일을 사용하여 flask를 실행합니다.

#!/usr/bin/env python
from datetime import datetime
from app import app
import config

if __name__ == '__main__':
    print '################### Restarting @', datetime.utcnow(), '###################'
    app.run(port=4004, debug=config.DEBUG, host='0.0.0.0')

서버를 시작하거나 파일이 업데이트되어 자동으로 다시 시작될 때 항상 인쇄 줄이 두 번 표시됩니다.

################### Restarting @ 2014-08-26 10:51:49.167062 ###################
################### Restarting @ 2014-08-26 10:51:49.607096 ###################

실제로 문제가되지는 않지만 (나머지는 예상대로 작동 함) 왜 이렇게 작동하는지 궁금합니다. 어떤 아이디어?



답변

Werkzeug 리 로더는 코드가 변경 될 때마다 해당 프로세스를 다시 시작할 수 있도록 자식 프로세스를 생성합니다. Werkzeug는 app.run().

restart_with_reloader()기능 코드를 참조하십시오 . 스크립트가 실행됩니다 다시subprocess.call().

사용자가 설정 한 경우 use_reloaderFalse볼 수 있습니다 당신 동작은 사라,하지만 당신은 또한 다시로드 기능을 잃게 :

app.run(port=4004, debug=config.DEBUG, host='0.0.0.0', use_reloader=False)

flask run명령을 사용할 때도 리 로더를 비활성화 할 수 있습니다 .

FLASK_DEBUG=1 flask run --no-reload

WERKZEUG_RUN_MAIN다시로드하는 하위 프로세스에있을 때 감지하려는 경우 환경 변수를 찾을 수 있습니다 .

import os
if os.environ.get('WERKZEUG_RUN_MAIN') == 'true':
    print '################### Restarting @ {} ###################'.format(
        datetime.utcnow())

그러나 모듈 전역을 설정해야하는 경우 대신 함수에 @app.before_first_request데코레이터 를 사용하고 해당 함수가 이러한 전역을 설정하도록해야합니다. 첫 번째 요청이 들어올 때마다 새로 고침 할 때마다 한 번만 호출됩니다.

@app.before_first_request
def before_first_request():
    print '########### Restarted, first request @ {} ############'.format(
        datetime.utcnow())

요청을 처리하기 위해 분기 또는 새 하위 프로세스를 사용하는 본격적인 WSGI 서버에서이를 실행하는 경우 해당 before_first_request처리기 각각의 새 하위 프로세스에 대해 호출 수 있다는 점을 고려하십시오 .


답변

최신 flask run명령을 사용하는 경우 app.run사용할 옵션이 없습니다. 리 로더를 완전히 비활성화하려면 --no-reload다음을 전달하십시오 .

FLASK_DEBUG=1 flask run --no-reload

또한 __name__ == '__main__'앱이 직접 실행되지 않기 때문에 절대 사실이 아닙니다. 블록이 없는 경우를 제외하고 Martijn의 답변 에서 동일한 아이디어를 사용하십시오 __main__.

if os.environ.get('WERKZEUG_RUN_MAIN') != 'true':
    # do something only once, before the reloader

if os.environ.get('WERKZEUG_RUN_MAIN') == 'true':
    # do something each reload


답변

저도 같은 문제가 있었는데, 내가 설정하여 그것을 해결 app.debugFalse. 그것을 설정하면 True__name__ == "__main__"전화가 두 번 호출되었습니다.


답변

플라스크 0.11에서이를 사용하여 응용 프로그램을 실행하는 것이 좋습니다 flask run보다는 python application.py. 후자를 사용하면 코드가 두 번 실행될 수 있습니다.

여기에 언급 된대로 :

… Flask 0.11부터 플라스크 방법을 권장합니다. 그 이유는 다시로드 메커니즘이 작동하는 방식으로 인해 특정 코드를 두 번 실행하는 것과 같은 기괴한 부작용이 있기 때문입니다.


답변

Flask 앱이 자체적으로 두 번 실행되는 가능한 이유 중 하나는 WEB_CONCURRENCYHeroku 의 설정 구성 때문입니다 . 하나로 설정하려면 콘솔에서 쓸 수 있습니다.
heroku config:set WEB_CONCURRENCY=1


답변

나는 같은 문제가 있었다. 내 메인을 수정하고 use_reloader = False를 삽입하여 해결했습니다. 여기에서이 문제에 대한 해결 방법을 찾고있는 경우 아래 코드에서 시작할 수 있지만 자동으로 감지되는 코드의 변경 기능이 작동하지 않으며 응용 프로그램을 다시 시작해도 작동하지 않습니다. 코드를 편집 할 때마다 애플리케이션을 수동으로 중지하고 다시 시작해야합니다.

if __name__ == '__main__':
    app.run(debug=True, use_reloader=False)


답변