ctrl-c를 사용하지 않고 플라스크 적용을 중지하는 방법
플라스크 스크립트를 사용하여 플라스크 적용을 중지할 수 있는 명령을 구현하고 싶습니다.저는 한동안 그 해결책을 찾아보았습니다.프레임워크가 제공하지 않기 때문입니다.app.stop()
API, 이것을 어떻게 코딩하는지 궁금합니다.저는 Ubuntu 12.10과 Python 2.7.3에서 일하고 있습니다.
데스크톱에서 서버를 실행하는 경우 엔드포인트를 노출하여 서버를 종료할 수 있습니다(단순 서버 종료에서 자세히 확인).
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.get('/shutdown')
def shutdown():
shutdown_server()
return 'Server shutting down...'
다음은 더 많이 포함된 또 다른 접근 방식입니다.
from multiprocessing import Process
server = Process(target=app.run)
server.start()
# ...
server.terminate()
server.join()
이게 도움이 된다면 알려주세요.
스레드를 사용하여 약간 다르게 했습니다.
from werkzeug.serving import make_server
class ServerThread(threading.Thread):
def __init__(self, app):
threading.Thread.__init__(self)
self.server = make_server('127.0.0.1', 5000, app)
self.ctx = app.app_context()
self.ctx.push()
def run(self):
log.info('starting server')
self.server.serve_forever()
def shutdown(self):
self.server.shutdown()
def start_server():
global server
app = flask.Flask('myapp')
# App routes defined here
server = ServerThread(app)
server.start()
log.info('server started')
def stop_server():
global server
server.shutdown()
저는 이것을 사용하여 python 요청 라이브러리를 사용하여 요청을 보낼 수 있는 restful api에 대한 엔드 투 엔드 테스트를 수행합니다.
이것은 약간 오래된 스레드이지만, 누군가 기본 플라스크 앱을 실험, 학습 또는 테스트하는 것이 백그라운드에서 실행되는 스크립트에서 시작된 경우 앱을 실행 중인 포트에서 실행 중인 프로세스를 종료하는 것이 가장 빠른 방법입니다.참고: 작성자가 앱을 종료하거나 중지하지 않는 방법을 찾고 있다는 것을 알고 있습니다.하지만 이것은 배우고 있는 누군가에게 도움이 될 수 있습니다.
sudo netstat -tulnp | grep :5001
이런 걸 얻게 될 겁니다.
tcp 00 0.0.0.0:5001 0.0.0.0:* LISTEN 28834/python
앱을 중지하려면 프로세스 중지
sudo kill 28834
내 방법은 bash 터미널/콘솔을 통해 진행할 수 있습니다.
실행하여 프로세스 번호 가져오기
$ ps aux | grep yourAppKeywords
2a) 프로세스 중단
$ kill processNum
2b) 위에서 작동하지 않을 경우 프로세스 종료
$ kill -9 processNum
했듯이, 은 다른사람이지이오, 은직듯당신만 할 수 .werkzeug.server.shutdown
요청 처리자로부터.다른 시간에 서버를 종료할 수 있는 유일한 방법은 자신에게 요청을 보내는 것입니다.를 들면, 를들어예,,/kill
는 다음 한 입니다.
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.post('/seriouslykill')
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.post('/kill')
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..."
이것은 오래된 질문이지만, 구글링은 제게 이것을 어떻게 달성할 수 있는지에 대한 통찰력을 주지 못했습니다.
내가 여기 코드를 제대로 읽지 못했기 때문에! (도!)그것이 하는 일은 a를 키우는 것입니다.RuntimeError
가 때werkzeug.server.shutdown
에 시대에request.environ
...
그래서 우리가 할 수 있는 것은 없을 때입니다.request
a를 키우는 것입니다.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
...
직접 요청할 필요가 없습니다.
CLI에서 작업 중이고 하나의 플라스크 앱/프로세스만 실행 중인 경우(또는 시스템에서 실행 중인 플라스크 프로세스를 종료하려는 경우) 다음을 사용하여 제거할 수 있습니다.
kill $(pgrep -f flask)
+를 누를 필요는 없지만 엔드포인트를 제공하여 다음 작업을 수행할 수 있습니다.
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
요청-응답 처리 범위 밖에 있는 경우에도 다음 작업을 수행할 수 있습니다.
import os
import signal
sig = getattr(signal, "SIGKILL", signal.SIGTERM)
os.kill(os.getpid(), sig)
request.environ.get
비권위의Pavel Minaev 솔루션은 매우 명확합니다.
import os
from flask import Flask
app = Flask(__name__)
exiting = False
@app.route("/exit")
def exit_app():
global exiting
exiting = True
return "Done"
@app.teardown_request
def teardown(exception):
if exiting:
os._exit(0)
만약 다른 사람이 win32 서비스 내에서 Flask 서버를 중지하는 방법을 찾고 있다면 - 여기 있습니다.여러 가지 접근 방식을 조합한 것은 좀 이상하지만, 잘 작동합니다.주요 아이디어:
- 은 이들은입니다.
shutdown
정상 종료에 사용할 수 있는 끝점입니다.참고: 다음에 의존합니다.request.environ.get
웹 요청의 컨텍스트 내에서만 사용할 수 있습니다(아래 참조)@app.route
function -ed 함수) - 32개의 서비스를 획득합니다.
SvcStop
는 메드사용을 합니다.requests
서비스 자체에 대한 HTTP 요청을 수행합니다.
나의 서비스
import win32service
import win32serviceutil
import win32event
import servicemanager
import time
import traceback
import os
import myservice
class MyServiceSvc(win32serviceutil.ServiceFramework):
_svc_name_ = "MyServiceSvc" # NET START/STOP the service by the following name
_svc_display_name_ = "Display name" # this text shows up as the service name in the SCM
_svc_description_ = "Description" # this text shows up as the description in the SCM
def __init__(self, args):
os.chdir(os.path.dirname(myservice.__file__))
win32serviceutil.ServiceFramework.__init__(self, args)
def SvcDoRun(self):
# ... some code skipped
myservice.start()
def SvcStop(self):
"""Called when we're being shut down"""
myservice.stop()
# tell the SCM we're shutting down
self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
servicemanager.LogMsg(servicemanager.EVENTLOG_INFORMATION_TYPE,
servicemanager.PYS_SERVICE_STOPPED,
(self._svc_name_, ''))
if __name__ == '__main__':
os.chdir(os.path.dirname(myservice.__file__))
win32serviceutil.HandleCommandLine(MyServiceSvc)
나의 봉사파이의
from flask import Flask, request, jsonify
# Workaround - otherwise doesn't work in windows service.
cli = sys.modules['flask.cli']
cli.show_server_banner = lambda *x: None
app = Flask('MyService')
# ... business logic endpoints are skipped.
@app.route("/shutdown", methods=['GET'])
def shutdown():
shutdown_func = request.environ.get('werkzeug.server.shutdown')
if shutdown_func is None:
raise RuntimeError('Not running werkzeug')
shutdown_func()
return "Shutting down..."
def start():
app.run(host='0.0.0.0', threaded=True, port=5001)
def stop():
import requests
resp = requests.get('http://0.0.0.0:5001/shutdown')
Python 솔루션
방법: 행실대:python kill_server.py
.
이것은 Windows 전용입니다.netstat과 함께 수집된 PID로 태스크킬을 수행하여 서버를 종료합니다.
# kill_server.py
import os
import subprocess
import re
port = 5000
host = '127.0.0.1'
cmd_newlines = r'\r\n'
host_port = host + ':' + str(port)
pid_regex = re.compile(r'[0-9]+$')
netstat = subprocess.run(['netstat', '-n', '-a', '-o'], stdout=subprocess.PIPE)
# Doesn't return correct PID info without precisely these flags
netstat = str(netstat)
lines = netstat.split(cmd_newlines)
for line in lines:
if host_port in line:
pid = pid_regex.findall(line)
if pid:
pid = pid[0]
os.system('taskkill /F /PID ' + str(pid))
# And finally delete the .pyc cache
os.system('del /S *.pyc')
favicon/index.html loading(예: 이전 버전이 캐시됨)에 대한 변경사항으로 문제가 있다면 Chrome에서도 "Clear Browsing Data > Images & Files"를 사용해 보십시오.
위의 모든 것들을 하면서, 저는 마침내 플라스크 앱을 실행할 때 제가 좋아하는 아이콘을 얻었습니다.
다음과 같이 자신의 PID를 죽이는 것이 효과가 있다는 것을 발견했습니다.
import os
from flask import Flask
app = Flask(__name__)
own_pid = os.getpid() # Get the main process's PID in a global variable
@app.route('/kill-backend')
def kill_backend():
global own_pid # Make sure to use the global variable
os.kill(own_pid, 9) # The second argument is the signal, 9 stands for SIGKILL.
#If you want to "politely ask" the server to quit you can use SIGQUIT (15) instead.
app.run(host='0.0.0.0', port=8000)
Ubuntu 22.04 LTS와 Window $10에서 테스트했습니다.둘 다 효과가 있습니다.
서버 킬을 트리거하려면 요청하십시오.http://127.0.0.1/kill-backend
그리고 그것은 실패하고 실패할 것입니다.connection refused
서버가 즉시 중지되었기 때문에 오류가 발생했습니다.
아래의 방법을 사용할 수 있습니다.
app.do_teardown_appcontext()
Google Cloud VM 인스턴스 + 플라스크 앱
Google Cloud Platform Virtual Machine 플라스크는 구글 클라우드 플랫폼 가상 머신입니다.는 나는앱시다니습했작을▁using를 사용하여 했습니다.python main.py
그러나 문제는 ctrl+c가 서버를 중지할 수 없다는 것입니다.
명령어는 다음과 같습니다.$ sudo netstat -tulnp | grep :5000
서버를 종료합니다.
내 플라스크 앱은 기본적으로 포트 5000에서 실행됩니다.
참고: 내 VM 인스턴스가 Linux 9에서 실행되고 있습니다.
이것에 효과가 있습니다.다른 플랫폼은 테스트하지 않았습니다.다른 버전에서도 작동한다면 언제든지 업데이트하거나 의견을 제시하십시오.
app = MyFlaskSubclass()
...
app.httpd = MyWSGIServerSubclass()
...
@app.route('/shutdown')
def app_shutdown():
from threading import Timer
t = Timer(5, app.httpd.shutdown)
t.start()
return "Server shut down"
My bash 스크립트 변형(LINUX):
#!/bin/bash
portFind="$1"
echo "Finding process on port: $portFind"
pid=$(netstat -tulnp | grep :"$1" | awk '{print $7}' | cut -f1 -d"/")
echo "Process found: $pid"
kill -9 $pid
echo "Process $pid killed"
사용 예:
sudo bash killWebServer.sh 2223
출력:
Finding process on port: 2223
Process found: 12706
Process 12706 killed
포트가 알려진 경우(예: 5000) 간단한 해결 방법은 다음과 같습니다.
fuser -k 5000/tcp
그러면 포트 5000의 프로세스가 중지됩니다.
Linux에서 특정 포트에서 실행 중인 프로세스를 종료하는 방법은 무엇입니까?
가 werkzeug라는 것입니다.BaseWSGIServer
에 의해 생성된 인스턴스werkzeug.serving.run_simple()
(이 이름은app.run()
)에 액세스할 수 없습니다.하지만 이 클래스는 클린을 정의합니다.shutdown()
해킹 없이 서버의 주 루프를 효과적으로 종료하는 방법입니다.
그래서 우리가 그 인스턴스에 접근할 수 있다면 서버를 죽일 수 있습니다.제가 생각할 수 있는 한 가지 방법은 쓰레기 수집가의 객체 추적입니다.
@app.route("/shutdown", methods=["POST"])
def shutdown():
for obj in gc.get_objects():
try:
if isinstance(obj, BaseWSGIServer):
obj.shutdown()
return "bye"
except:
pass
return "failed"
저는 유닛 테스트에서 POST 콜백을 만드는 것을 모방하기 위해 이것이 필요하다는 것을 알게 되었습니다.이 기능을 사용하면 플라스크 서버를 스레드로 실행할 수 있으며 다른 테스트를 실행하는 동안에도 서버가 계속 작동할 걱정을 하지 않습니다.
Windows의 경우 플라스크 서버를 중지/제거하는 것이 매우 쉽습니다.
- 작업 관리자로 이동
- 플라스크를 찾습니다.exe
- 프로세스 선택 및 종료
언급URL : https://stackoverflow.com/questions/15562446/how-to-stop-flask-application-without-using-ctrl-c
'programing' 카테고리의 다른 글
오늘 날짜와 결과를 비교하시겠습니까? (0) | 2023.07.03 |
---|---|
여기에 "오픈 깃배시"를 추가하는 방법.윈도우 탐색기의 상황에 맞는 메뉴? (0) | 2023.07.03 |
ASP.Net 마스터 페이지 및 파일 경로 문제 (0) | 2023.07.03 |
Oracle 씬 드라이버 대 OCI 드라이버.장점과 단점? (0) | 2023.07.03 |
SQL Server 데이터베이스에서 모든 저장 프로시저를 한 번에 삭제하는 방법은 무엇입니까? (0) | 2023.07.03 |