Ctrl-C를 사용하지 않고 플라스크 응용 프로그램을 중지하는 방법


104

플라스크 스크립트를 사용하여 플라스크 응용 프로그램을 중지 할 수있는 명령을 구현하고 싶습니다. 나는 잠시 동안 해결책을 찾았습니다. 프레임 워크는 "app.stop ()"API를 제공하지 않기 때문에 코드 작성 방법이 궁금합니다. Ubuntu 12.10 및 Python 2.7.3에서 작업 중입니다.


스크립트에서 애플리케이션을 중지 할 수 있어야하는 이유는 무엇입니까? (작업에 가장 적합한 도구는 수행하려는 작업에 따라 다릅니다).
Sean Vieira 2013 년

진심으로, 여기서 뭘하려는거야? 개발 용 devserver에 대해 이야기하고 있다면 그렇게 멈춰도 괜찮습니다. 프로덕션에서는 이와 같이 배포하지 않으며 언제든지 요청을 중지 할 수 있으므로 "앱 실행이 중지"됩니다.
Ignas Butėnas 2013 년

@SeanVieira 나는 이것을 할 해결책이 있는지 알고 싶습니다.
vic

@IgnasB. 지금 내 컴퓨터에서 RESTful 서비스를 개발 중입니다. 프로젝트를 진행하고 있는데 배포 할 머신을 선택하는 데 도움이 될 수 있습니다. 내가 알아낼 수있는 유일한 방법은 프로세스를 종료하여 종료하는 것입니다.
피해자

3
@vrootic이지만 어쨌든 프로덕션에서는 app.run ()을 사용하지 않습니다. app.run ()은 개발 및 개발 중 애플리케이션 테스트에만 사용됩니다. 프로덕션 환경에서 Flask를 실행하는 방법에는 여러 가지가 있습니다. 예를 들어 flask.pocoo.org/docs/quickstart/#deploying-to-a-web-server 와 같은 방법으로 이미 배포 한 경우 (그래서 오해했습니다. 질문), Flask로 오는 요청 제공을 중지하는 방법은 요청을 제공하는 http 서버를 중지하는 것입니다.
Ignas Butėnas 2013 년

답변:


125

데스크톱에서 서버를 실행하는 경우 엔드 포인트를 노출하여 서버를 종료 할 수 있습니다 (자세한 내용은 Shutdown The Simple Server 참조 ).

from flask import request
def shutdown_server():
    func = request.environ.get('werkzeug.server.shutdown')
    if func is None:
        raise RuntimeError('Not running with the Werkzeug Server')
    func()

@app.route('/shutdown', methods=['POST'])
def shutdown():
    shutdown_server()
    return 'Server shutting down...'

다음은 더 포함 된 또 다른 접근 방식입니다.

from multiprocessing import Process

server = Process(target=app.run)
server.start()
# ...
server.terminate()
server.join()

이것이 도움이되는지 알려주세요.


16
요청 컨텍스트없이 'werkzeug.server.shutdown'속성을 가져올 수있는 방법이 있는지 알고 있습니까?
akatkinson

5
작동하려면 경로 방법을 'GET'으로 변경해야했습니다.
CS

5
완전성을 위해이 답변에는 요청 컨텍스트 외부에서 호출하여 종료를 수행하는 함수가 없습니다. 이는 서버에 대한 HTTP 요청에 지나지 않습니다 (localhost에서
시작될 수 있음

1
methods='POST', 내가 얻을 405 Method not allowed@CS이 제안 방법과 = 'GET'`이 작동하는 반면, 오류가 발생했습니다.
Agile Bean

1
AWS Elastic Beanstalk에서 저에게 적합하지 않았습니다. 물론 로컬 근무
안드레이 Bulezyuk

34

실을 사용하여 약간 다르게했습니다

from werkzeug.serving import make_server

class ServerThread(threading.Thread):

    def __init__(self, app):
        threading.Thread.__init__(self)
        self.srv = make_server('127.0.0.1', 5000, app)
        self.ctx = app.app_context()
        self.ctx.push()

    def run(self):
        log.info('starting server')
        self.srv.serve_forever()

    def shutdown(self):
        self.srv.shutdown()

def start_server():
    global server
    app = flask.Flask('myapp')
    ...
    server = ServerThread(app)
    server.start()
    log.info('server started')

def stop_server():
    global server
    server.shutdown()

파이썬 요청 라이브러리를 사용하여 요청을 보낼 수있는 안정적인 API에 대한 종단 간 테스트를 수행하는 데 사용합니다.


2
다른 작업을 수행하지 못했지만이 솔루션은 훌륭하게 작동합니다! 정말 감사합니다! 다른 사람들을 위해 : 그것은 또한 편안한 플라스크와 함께 작동합니다!
Jorrick Sleijster

이것은 내가 다른 요청으로 그것을 칠 때까지 창문에서 차단되는 것 같습니다.
Claudiu

python 3.6.2가있는 Linux를 제외하고 @Claudiu와 동일한 문제가 있습니다.
micahscopes

왜 이것이 허용되지 않는지 모르겠지만 가장 깨끗하고 추가 종속성없이 훌륭하게 작동합니다. 정말 고마워.
Eric Reed

17

이것은 약간 오래된 스레드이지만, 누군가가 백그라운드에서 실행되는 스크립트에서 시작된 기본 플라스크 앱을 실험, 학습 또는 테스트하는 경우이를 중지하는 가장 빠른 방법은 앱을 실행중인 포트에서 실행중인 프로세스를 종료하는 것입니다. 의 위에. 참고 : 저자가 앱을 종료하거나 중지하지 않는 방법을 찾고 있다는 것을 알고 있습니다. 그러나 이것은 배우는 사람에게 도움이 될 수 있습니다.

sudo netstat -tulnp | grep :5001

당신은 이와 같은 것을 얻을 것입니다.

tcp 00 0.0.0.0:5001 0.0.0.0:* LISTEN 28834 / python

앱을 중지하려면 프로세스를 종료하십시오.

sudo kill 28834

15

내 방법은 bash 터미널 / 콘솔을 통해 진행할 수 있습니다.

1) 실행하고 프로세스 번호 얻기

$ ps aux | grep yourAppKeywords

2a) 프로세스 종료

$ kill processNum

2b) 위가 작동하지 않으면 프로세스를 종료하십시오.

$ kill -9 processNum

9
나는 그 질문이 "프로세스를 죽이는 방법"이 아니라고 거의 확신하며, 문제는 ctrl + c를하더라도 죽이지 않는다는 것입니다. Btw, 나는 kill -9 `lsof -i:5000 -t`단지 하나의 앱만이 포트를 사용할 수 있고 쉬우므로 사용하고 있습니다.
m3nda

9

다른 사람들이 지적했듯이 werkzeug.server.shutdown요청 핸들러 에서만 사용할 수 있습니다 . 다른 시간에 서버를 종료하는 유일한 방법은 자신에게 요청을 보내는 것입니다. 예를 들어, /kill이 스 니펫 의 핸들러는 다음 1 초 동안 다른 요청이 들어오지 않는 한 dev 서버를 종료합니다.

import requests
from threading import Timer
from flask import request
import time

LAST_REQUEST_MS = 0
@app.before_request
def update_last_request_ms():
    global LAST_REQUEST_MS
    LAST_REQUEST_MS = time.time() * 1000


@app.route('/seriouslykill', methods=['POST'])
def seriouslykill():
    func = request.environ.get('werkzeug.server.shutdown')
    if func is None:
        raise RuntimeError('Not running with the Werkzeug Server')
    func()
    return "Shutting down..."


@app.route('/kill', methods=['POST'])
def kill():
    last_ms = LAST_REQUEST_MS
    def shutdown():
        if LAST_REQUEST_MS <= last_ms:  # subsequent requests abort shutdown
            requests.post('http://localhost:5000/seriouslykill')
        else:
            pass

    Timer(1.0, shutdown).start()  # wait 1 second
    return "Shutting down..."

2
이것은 작동하지만 ... 매우 엉망입니다. 오랜만이라는 건 알지만, 자신에게 요청을 보내지 않고 깨끗한 방법을 찾은 적이 있습니까?
Juicy

7

이것은 오래된 질문이지만 인터넷 검색은 이것을 수행하는 방법에 대한 통찰력을주지 못했습니다.

여기서 코드를 제대로 읽지 않았기 때문에 ! (DOH는!) 그것이 무엇을하는 것은 인상하지 않는 것입니다 RuntimeError더있을 때 werkzeug.server.shutdownrequest.environ...

그래서 우리가 할 수있는 request것은RuntimeError

def shutdown():
    raise RuntimeError("Server going down")

app.run()돌아올 때 잡아라 .

...
try:
    app.run(host="0.0.0.0")
except RuntimeError, msg:
    if str(msg) == "Server going down":
        pass # or whatever you want to do when the server goes down
    else:
        # appropriate handling/logging of other runtime errors
# and so on
...

자신에게 요청을 보낼 필요가 없습니다.


4

"CTRL-C"를 누를 필요는 없지만이를 수행하는 엔드 포인트를 제공 할 수 있습니다.

from flask import Flask, jsonify, request
import json, os, signal

@app.route('/stopServer', methods=['GET'])
def stopServer():
    os.kill(os.getpid(), signal.SIGINT)
    return jsonify({ "success": True, "message": "Server is shutting down..." })

이제이 끝점을 호출하여 서버를 정상적으로 종료 할 수 있습니다.

curl localhost:5000/stopServer

코드를 테스트했지만 이후 os.kill에 반환 된 응답을 클라이언트가받을 수 없습니다. 의 경우 curl"curl : (56) Recv failure : Connection was reset"을 출력합니다. Flask가 문제를 해결하기 위해 응답반환 한 후 함수 실행 도 참조 할 수 있습니다.
samm

@samm, 그 질문의 결론은 다른 스레드를 시작하지 않으면 불가능하다는 것입니다. 그렇다면 다른 스레드에서 플라스크 서버를 어떻게 종료합니까?
Jurgy

3

다음 방법을 사용할 수 있습니다.

app.do_teardown_appcontext()

2

당신과 CLI에서 작업하는 경우에만 실행 한 플라스크 응용 프로그램 / 프로세스가 (또는 오히려, 당신은 단지 죽이고 싶어하려는 어떤 당신이 그것을 죽일 수, 시스템에서 실행 플라스크 프로세스) :

kill $(pgrep -f flask)


1

요청-응답 처리를 벗어난 경우에도 다음을 수행 할 수 있습니다.

import os
import signal

sig = getattr(signal, "SIGKILL", signal.SIGTERM)
os.kill(os.getpid(), sig)

0

Google Cloud VM 인스턴스 + Flask 앱

Google Cloud Platform 가상 머신에서 Flask 애플리케이션을 호스팅했습니다. 나는 사용하여 앱을 시작했습니다.python main.py 했지만 문제는 ctrl + c가 서버를 중지하는 데 작동하지 않는다는 것입니다.

이 명령 $ sudo netstat -tulnp | grep :5000 은 서버를 종료합니다.

내 Flask 앱은 기본적으로 포트 5000에서 실행됩니다.

참고 : 내 VM 인스턴스는 Linux 9에서 실행됩니다.

이를 위해 작동합니다. 다른 플랫폼에 대해서는 테스트하지 않았습니다. 다른 버전에서도 작동한다면 자유롭게 업데이트하거나 의견을 말하십시오.


-1

Windows의 경우 플라스크 서버를 중지 / 종료하는 것은 매우 쉽습니다.

  1. 작업 관리자로 이동
  2. flask.exe 찾기
  3. 프로세스 선택 및 종료

10
컴퓨터의 전원 버튼도 매우 효과적입니다. haha
Michael Green
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.