【发布时间】:2024-05-20 20:40:01
【问题描述】:
我正在使用 tornado 实现 REST api,并希望它是非阻塞的。
目前,与问题相关的代码如下:
class ReprsHandler(web.RequestHandler):
async def get(self, name):
db = await dbf.create_handler()
if 'id' in list(self.request.query_arguments.keys()):
db_future = asyncio.ensure_future(db.get_repr(name, self.get_query_argument('id')))
else:
db_future = asyncio.ensure_future(db.get_reprs(name))
result = await db_future
response = result.toSerializedStream()
self.set_status(HTTPStatus.OK)
self.write(response)
self.set_header('Content-Type', 'text/plain')
self.finish()
class App(object):
def __init__(self, loop):
self.server_app = web.Application(
handlers=[
(r"/api/v1/([a-zA-Z0-9_-]+)/reprs", ReprsHandler),
]
)
def main():
AsyncIOMainLoop().install()
loop = asyncio.get_event_loop()
app = App(loop)
server = tornado.httpserver.HTTPServer(app.server_app, max_body_size=config['max_upload_size'], max_buffer_size=config['max_upload_size'])
server.bind(config['server_port'])
server.start()
loop.run_forever()
代码比较简单,但是数据量比较大,所以大概需要3~4分钟才能全部发送完。
我希望处理程序的逻辑和网络 IO 都是非阻塞的,但它会在发送数据作为响应时阻塞服务器网络。逻辑很好。他们不会阻止其他请求。
详情:
- 此代码在 docker 上运行,ubuntu 16.04,使用 python 3.5 实现。
- 服务器正在使用 nginx 作为端口代理。
可能是什么问题?我不知道是什么造成了这个问题。
【问题讨论】:
-
result.toSerializedStream()是做什么的?既然您提到“数据非常大”,我假设result变量是数据并且它很大。因此,如果.toSerializedStream()对大数据执行任何 CPU 密集型任务,那么这可能是阻塞的原因。 -
该方法使用pickle转储生成数据对象的序列化字符串,但逻辑的时间成本没有网络成本那么大。不过,我可以对此进行一些性能改进。谢谢。
标签: python python-3.x nginx tornado