[python] 로컬 Flask 서버에서 느린 요청

로컬 서버에서 Flask를 가지고 놀기 시작했는데 요청 / 응답 시간이 내가 생각하는 것보다 훨씬 느리다는 것을 알았습니다.

다음과 같은 간단한 서버가 응답하는 데 약 5 초가 걸립니다.

from flask import Flask

app = Flask(__name__)

@app.route("/")
def index():
    return "index"

if __name__ == "__main__":
    app.run()

어떤 아이디어? 아니면 이것이 바로 로컬 서버입니까?



답변

좋아, 알아 냈어. ipv6를 지원하는 Werkzeug 및 OS의 문제인 것으로 보입니다.

Werkzeug 사이트 http://werkzeug.pocoo.org/docs/serving/에서 :

최신 Linux 시스템, OS X 10.4 이상 및 Windows Vista와 같이 ipv6을 지원하고 구성한 운영 체제에서 일부 브라우저는 로컬 서버에 액세스 할 때 고통스럽게 느려질 수 있습니다. 그 이유는 때때로 “localhost”가 ipv4 및 ipv6 양말 모두에서 사용 가능하도록 구성되어 있고 일부 브라우저는 먼저 ipv6에 액세스 한 다음 ivp4에 액세스하려고 시도하기 때문입니다.

따라서 수정은 내 호스트 파일에서 다음 줄을 주석 처리하여 localhost에서 ipv6을 비활성화하는 것입니다.

::1             localhost

이렇게하면 지연 문제가 사라집니다.

저는 Flask를 정말로 파고 있으며 프레임 워크에 문제가 없다는 것이 기쁩니다. 나는 그럴 수 없다는 것을 알고 있었다.


답변

http://arusahni.net/blog/2013/10/flask-multithreading.html에 제안 된대로 app.run ()에 인수로 “threaded = True”를 추가합니다.

예를 들면 : app.run(host="0.0.0.0", port=8080, threaded=True)

ipv6 비활성화 솔루션은 저에게 효과가 없었지만 효과가있었습니다.


답변

@ sajid-siddiqi의 솔루션은 기술적으로 정확하지만 Werkzeug 에 내장 된 WSGI 서버 ( Flask에 패키지로 포함되어 있으며 용도에 사용되는 것 )는 단일 스레드 일 뿐이 라는 점을 명심 하십시오 .app.run()

다중 스레드 동작을 처리 할 수 ​​있도록 WSGI 서버를 설치합니다 . 다양한 WSGI 서버 성능 에 대해 많은 연구를했습니다 . 귀하의 요구 사항은 다를 수 있지만 사용중인 모든 것이 Flask 인 경우 다음 웹 서버 중 하나를 권장합니다.

업데이트 (2020-07-25) : geventpython3을 지원 하지 않는다고 언급 한 직후 5 년 전부터 gevent를 지원하기 시작한 것 같습니다 . 지금 gevent 를 사용할 수 있습니다 .

gevent

당신은 설치할 수 있습니다 gevent을 통해 PIP 명령으로 pip install gevent또는 pip3 명령으로 pip3 install gevent. 이에 따라 코드를 수정하는 방법에 대한 지침은 https://flask.palletsprojects.com/en/1.1.x/deploying/wsgi-standalone/#gevent에 있습니다.

Meinheld

gevent 가 더 좋지만 실제 테스트와 관련된 모든 벤치 마크에서 meinheld 는 가장 간단하고 단순한 WSGI 서버 인 것 같습니다 . ( 더 많은 구성이 마음에 들지 않으면 uWSGI를 살펴볼 수도 있습니다 .)

명령을 사용하여 pip3을 통해 meinheld 를 설치할 수도 있습니다 pip3 install meinheld. 여기에서 meinheld 소스에 제공된 샘플을보고 Flask 를 통합합니다 . https://github.com/mopemope/meinheld/blob/master/example/flask_sample.py

* 참고 : PyCharm 사용시 줄 from meinheld import server이 오류로 강조 표시되지만 서버가 실행되므로 오류를 무시할 수 있습니다.


답변

http://localhost:port/endpointcall 을 호출하는 대신 http://127.0.0.1:port/endpoint. 이것은 나를 위해 초기 500ms 지연을 제거했습니다.


답변

내 문제는 “threaded = True”로 해결되었지만 내 문제를 다른 문제와 구별 할 수있는 배경을 제공하고 싶습니다.

  1. 내 문제는 python3으로 Flask를 실행할 때만 발생했습니다. python2로 전환하면 더 이상이 문제가 발생하지 않았습니다.
  2. 내 문제 는 Chrome으로 API에 액세스 할 때만 나타났습니다 . 그 시점에서 Chrome은 예상 화면을 표시했지만 다른 모든 것은 Chrome 탭을 다시로드하거나 닫을 때까지 (curl, ffx 등) 중단되었습니다. 주위에 결과가 반환되었습니다.

내 추측으로는 Chrome이 세션을 열어 두려고하고 Flask가 후속 요청을 차단하고 있다는 것입니다. Chrome에서의 연결이 중지되거나 재설정 되 자마자 다른 모든 것이 처리되었습니다.

제 경우에는 스레딩이 문제를 해결했습니다. 물론 다른 문제가 발생하지 않도록 다른 사람들이 제공 한 링크 중 일부를 살펴 보겠습니다.


답변

threaded=True나를 위해 작동하지만 마침내 문제가 firefox의 foxyproxy 때문이라는 것을 알게되었습니다. 플라스크 앱이 localhost에서 실행 중일 때

  • foxyproxy가 firefox에서 활성화되었습니다.

느린 응답이 발생하지 않는 경우

  • foxyproxy가 firefox에서 비활성화되었습니다.

  • 다른 브라우저를 사용하여 웹 사이트에 액세스

내가 찾은 유일한 해결책은 foxyproxy를 비활성화하고 localhost를 프록시 블랙리스트에 추가하고 설정을 조정했지만 아무것도 작동하지 않는 것입니다.


답변

Miheko의 답변을 사용하여 문제를 해결했습니다.

::1 localhost내 호스트 파일에 이미 주석 처리되었으며 설정 Threaded=true이 작동하지 않았습니다. 모든 REST 요청은 즉시 처리되는 대신 1 초가 소요되었습니다.

저는 python 3.6을 사용하고 있으며, flask가 WSGI로 gevent를 사용하도록하여 flask가 REST 요청에 빠르고 응답하도록했습니다.

gevent를 사용하려면 다음과 같이 설치하십시오. pip install gevent

그 후 https://gist.github.com/viksit/b6733fe1afdf5bb84a40#file-async_flask-py-L41 을 사용하여 플라스크를 gevent를 사용하도록 설정했습니다.

링크가 다운되는 경우 스크립트의 중요한 부분은 다음과 같습니다.

from flask import Flask, Response
from gevent.pywsgi import WSGIServer
from gevent import monkey

# need to patch sockets to make requests async
# you may also need to call this before importing other packages that setup ssl
monkey.patch_all()

app = Flask(__name__)


# define some REST endpoints... 

def main():

    # use gevent WSGI server instead of the Flask
    # instead of 5000, you can define whatever port you want.
    http = WSGIServer(('', 5000), app.wsgi_app)

    # Serve your application
    http.serve_forever()


if __name__ == '__main__':
    main()