想象一下以下龍捲風應用:爲什麼Tornado的WSGI支持會阻止多個請求?
import logging
import time
from tornado import gen, httpserver, ioloop, web, wsgi
def simple_app(environ, start_response):
time.sleep(1)
status = "200 OK"
response_headers = [("Content-type", "text/plain")]
start_response(status, response_headers)
return [b"Hello, WSGI world!\n"]
class HelloHandler(web.RequestHandler):
@gen.coroutine
def get(self):
yield gen.moment
self.write('Hello from tornado\n')
self.finish()
def main():
wsgi_app = wsgi.WSGIContainer(simple_app)
tornado_app = web.Application(
[
('/tornado', HelloHandler),
('.*', web.FallbackHandler, dict(fallback=wsgi_app)),
],
debug=True,
)
http_server = httpserver.HTTPServer(tornado_app)
http_server.listen(8888)
current_loop = ioloop.IOLoop.current()
current_loop.start()
if __name__ == '__main__':
main()
現在,如果你運行這個並試圖讓http://localhost:8888/
龍捲風塊,直到WSGI請求完成(一秒睡眠後在這裏)。這件事我知道。但是,如果您一個接一個地發送很多請求,那麼IOLoop可能會永久封鎖。
我想這樣的標杆:
$ ab -n 20 -c 2 localhost:8888
在第二端我試圖讓其他網址:
$ curl http://localhost:8888/tornado
我得到了非WSGI請求的響應直到所有其他併發的WSGI請求已完成。這僅適用於已刪除yield gen.moment
的情況。
任何人都可以解釋這裏發生了什麼,以及如何防止Tornado阻止我的所有請求,而不僅僅是其中之一?
非常感謝。我將WSGI和Tornado結合起來可以帶來一些好處,所以我希望通過稍後使用優先級隊列來減少阻塞問題,以便在一次阻塞WSGI調用後,Tornado運行IOLoop,並且每個人都有機會在下一次之前進入中間層阻止WSGI呼叫。但是,如果Tornado沒有運行IOLoop,只要有任何*未完成的WSGI請求,這將不起作用。 – Norman8054