Tornado并发与异步需求

2024-04-26 06:58:39 发布

您现在位置:Python中文网/ 问答频道 /正文

假设我的web服务器有大约100 req/秒的负载。我有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()

参见here关于在Tornado中发出非阻塞请求。 特别是使用默认线程池执行器,如:

executor = concurrent.futures.ThreadPoolExecutor(5)

我正在使用(希望是)更好的实现来限制并发线程的数量,以避免内存压力:

executor = BoundedThreadPoolExecutor(max_workers=5)

有关BoundedThreadPoolExecutor的实现,请参见this包。你知道吗

这似乎行得通。出于性能原因,我尝试将以前的light tasks请求从@tornado.web.asynchronous模式移到@tornado.concurrent.run_on_executor模式,这里我遇到了一个问题。在某个时刻,服务器停止服务请求,没有崩溃,没有运行时错误。它只是停止接收请求,并在机器上提供带有任何错误或OOM问题的响应。我尝试了不同大小的max_workers工作者队列,从5个并发工作者到100个并发工作者,但没有明显效果。你知道吗


Tags: runself服务器webdataondefpost