假定我的Web服务器的负载约为100 req / sec。并且我有70%的请求受I / O绑定并执行轻量级任务(如db查询),而30%的cpu绑定则进行繁重的任务(如哈希,计算以及文件系统上的资源) 。后面的请求也是I / O阻止,因此我使用ThreadPoolExecutor
来避免它们将阻止更快的请求:
@tornado.concurrent.run_on_executor
def post(self, *args):
# I'm a io blocking request
data = heavy_load_task()
self.write(data)
70%的请求是通过asynchronous
装饰器实现的,因此请求对self.finish()
的特定调用以显式关闭套接字:
@tornado.web.asynchronous
def post(self, *args):
# I'm a light request
data = light_load_task()
self.write(data)
self.finish()
有关在Tornado中发出非阻塞请求的信息,请参见here。 特别是使用默认的线程池执行程序,例如:
executor = concurrent.futures.ThreadPoolExecutor(5)
我正在使用(希望)更好的实现,它希望限制并发线程的数量以避免内存压力:
executor = BoundedThreadPoolExecutor(max_workers=5)
有关BoundedThreadPoolExecutor
的实现,请参见this软件包。
这似乎正常。出于性能原因,我试图将以前的轻型任务请求从@tornado.web.asynchronous
模式转移到@tornado.concurrent.run_on_executor
模式,但是这里出现了问题。在某个时候服务器停止服务请求,没有崩溃,没有运行时错误。它只是停止获取请求并在计算机上出现任何错误或OOM问题时提供响应。我尝试了从5到100个并发工作人员使用不同大小的max_workers
工作人员队列,但没有明显效果。