로컬 Flask 서버에서 느린 요청


87

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

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

from flask import Flask

app = Flask(__name__)

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

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

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


로컬 서버는 아니지만 백그라운드에서 실행되는 다른 응용 프로그램과 관련이있을 수 있습니다. 어떤 OS에서 이것을 실행하고 있습니까?
gabeio

나는 I7 아이맥 OS X 10.7에서 실행 해요
Meroon

1
귀하의 답변에 이렇게 오래 걸리지 않아야합니다.하지만 실제로 전에 플라스크를 엉망으로 만들었습니다 . 여전히 백그라운드 프로세스를 확인하더라도 백그라운드에서 실행중인 서버의 이전 버전이 Python을 인수하여 느린 응답을 유발할 수 있습니다. 또한 브라우저가 크롬 및 사파리에서 발생합니까?
gabeio

2
@Meroon의 대답이 맞았습니다. 그러나 호스트 설정을 변경하는 대신 : localhost 대신 127.0.0.1을 사용하는 것이 좋습니다. 시스템 구성을 변경하지 않고도 문제가 해결되었습니다.
David Bernat

답변:


93

좋아, 알아 냈어. 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를 정말로 파고 있으며 프레임 워크에 문제가 없다는 것이 기쁩니다. 나는 그럴 수 없다는 것을 알고 있었다.



감사합니다! 갑자기 개발 테스트가 빠르고 반응이 좋습니다! 내 유일한 질문 : Mac 호스트 파일은 localhost를 제거하면 내 Mac의 작업에 영향을 미칠 수 있음을 나타내므로이 줄 (또는 단순히 localhost를 127.0.0.1로 찾는 줄)을 참조하고 있는지 궁금합니다
David B.

내 Windows 10 시스템에서 호스트 파일의 두 항목 (ip4 및 ip6)이 모두 주석 처리됩니다. DNS 시스템에 의해 해결됩니다. "localhost"대신 "127.0.0.1"에서 서버를 실행했을 때 속도가 엄청나게 증가했습니다 (간단한 호출의 경우 2.0 초에서 0.003 초로)
Lars

이 답변에 감사드립니다! 내 상황은 약간 달랐지만 (aiosmtpd에 대해 nose2 실행) 대답은 나에게 힌트를주었습니다. Windows 10 랩톱에서 IPv6비활성화 하면 10x 또는 100x와 같은 속도가 빨라집니다!
pepoluan

87

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 비활성화 솔루션은 저에게 효과가 없었지만 효과가있었습니다.


5
--threadedmanage.py사용에 전달 하는 것도 Flask-Script효과가 있습니다.
Snorfalorpagus

7
스레드를 활성화하여 "고정"된 경우 경고를 받으십시오! 이 경우 지연은 이전 요청이 제대로 닫히지 않았기 때문에 실제로 많은 스레드를 스택하고 있습니다 .
kbtz

내 로컬 호스트를 엄청나게 빠르게 실행시켜 주셔서 감사합니다.
benjaminz

@snolflake : 요청이 제대로 닫히지 않았는지 알 수있는 방법이 있습니까?
Kylotan

1
명령 줄에서 flask run --with-threads내 문제를 해결하는 데 사용했습니다 .
arno_v 2011

13

@ 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이 오류로 강조 표시되지만 서버가 실행되므로 오류를 무시할 수 있습니다.


Flask에 큰 성능 문제가 있었는데 가장 간단한 요청조차도 완료하는 데 약 0.5 초가 걸렸습니다. gevent로 전환하고 모든 것이 완벽하게 작동합니다. 감사합니다!
gronostaj 2015 년

7

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


나를 위해 그것은 3seconds와 같은 것을 제거했습니다 (0.0.0.0에서 127.0.0.1로 이동했습니다). 누군가 왜 그리고 어떻게 작동하는지 설명 할 수 있습니까?
Rotkiv

신의 이름으로 이것이 작동하는 이유는 무엇입니까? 2.06 초에서 0.002 초로 변경되었습니다. 브라우저는 문제없이 localhost를 사용할 수 있지만 localhost의 requests.get을 해결하는 데 2 ​​초가 걸립니다.
Xevion

7

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

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

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

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


4

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

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

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

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

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

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


2

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()

threaded = True가 작동하지 않습니다 (python 3.6.7 및 postman 사용), VersionConflict : (greenlet 0.4.13 (c : \ anaconda3 \ lib \ site-packages), Requirement.parse ( 'greenlet> = 0.4. 14; platform_python_implementation == "CPython과는" ')), 나는이 문제를 해결하는 방법을 감사 알 수 있습니다
hanzgs

0

다른 호스트에서도 실행할 때이 오류가 발생 localhost하므로 일부 다른 기본 문제가 동일한 증상을 나타낼 수 있습니다.

나는 내가 사용했던 대부분의 것을 Tornado로 전환했고, 일화 적으로 그것은 많은 도움이되었습니다. 몇 가지 느린 페이지로드가 있었지만 일반적으로 반응이 더 빠른 것 같습니다. 또한 매우 일화 적이지만 Flask만으로는 시간이 지남에 따라 속도가 느려지지만 Flask + Tornado는 덜 느립니다. Apache를 사용 mod_wsgi하는 것이 더 좋을 것이라고 생각 하지만 Tornado는 설정이 정말 간단합니다 ( http://flask.pocoo.org/docs/deploying/others/ 참조 ).

(또한 관련 질문 : Flask 앱이 때때로 중단됨 )


0

여기에 다른 해결책이 있습니다. 방금 .pyc서버 디렉토리에서 모두 삭제 하고 다시 시작했습니다. 그건 그렇고, localhost는 이미 내 호스트 파일 (Windows 8)에서 주석 처리되었습니다.

서버가 계속 멈 췄고 이제 다시 정상적으로 작동합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.