【发布时间】:2016-06-12 16:22:45
【问题描述】:
想象一下以下龙卷风应用:
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/ tornado 块,直到 WSGI 请求完成(这里是在一秒钟后休眠)。这件事我知道。但是,如果您一个接一个地发送许多请求,那么 IOLoop 可能会永远阻塞。
我尝试了这样的基准测试:
$ ab -n 20 -c 2 localhost:8888
在第二个终端中,我尝试获取另一个网址:
$ curl http://localhost:8888/tornado
直到所有其他并发 WSGI 请求完成后,我才收到非 WSGI 请求的响应。这仅在删除 yield gen.moment 时有效。
谁能解释这里发生了什么以及如何防止 Tornado 阻止我的所有请求,而不仅仅是其中一个?
【问题讨论】:
标签: python-3.x tornado wsgi