私はトルネードでREST APIを実装しており、それを非ブロックにしたいと考えています。python TornadoハンドラIOがサーバーネットワーク全体をブロックする
は現在、問題に関連するコードは次のようになります:
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が両方ともノンブロッキングであると予想されましたが、応答としてデータを送信しながらサーバーネットワークをブロックします。論理は良いです。彼らは他の要求をブロックしません。
詳細:
- このコードは、Python 3.5で実装され、Ubuntuの16.04、ドッキングウィンドウ上で実行されます。
- サーバがポートプロキシとしてnginxを使用しています。
何か問題がありますか?私はこの問題の原因を知りません。
'result.toSerializedStream()'とは何ですか?あなたは "データがかなり大きい"と述べているので、私は 'result'変数がデータであり、それが大きいと仮定しています。だから、 '.toSerializedStream()'が大量のデータに対してCPUバインドされたタスクを実行すると、それがブロックの理由になるかもしれません。 – xyres
このメソッドは、データオブジェクトのシリアル化された文字列を生成するためにpickleダンプを使用しますが、ロジックの時間コストはネットワーキングコストほど大きくはありません。それでも、私はパフォーマンスの改善を行うことができます。ありがとう。 –