Tornado服务请求超时问题:如何从接收时刻设置超时防CPU过载?
问题:Tornado服务PDF解析的请求超时与CPU过载问题
我搭建了一个Tornado Web服务,用于接收并处理请求、解析PDF文档。核心问题是将PDF加载为XML树的操作耗时极长且会造成CPU阻塞。
当异步发送约90个请求时,它们会同时到达服务器:
- 部分请求能正常得到响应
- 部分请求会在30秒后超时,但服务器仍会继续处理这些已超时的请求,长此以往会导致服务器拥堵
已尝试的解决方案
方案一:使用独立线程处理PDF
通过run_in_executor把PDF处理逻辑放到线程中,并设置超时。但服务器同时接收并处理所有请求,导致单请求耗时增加,不过该方式能为每个线程设置超时:
class PdfExHandler(tornado.web.RequestHandler): def post(self): future = asyncio.get_event_loop().run_in_executor(None, self.long_running_func, args) await asyncio.wait_for(future, timeout=30, loop=asyncio.get_event_loop()) def long_running_func(self, args): res = processPDF(args) self.write(json.dumps(res))
方案二:设置异步Timer
尝试用Timer实现超时逻辑,但Timer仅从PDF处理开始时刻计时,而非请求初始到达时刻,不符合需求:
class PdfExHandler(tornado.web.RequestHandler): async def timeout_callback(): raise Exception("Timeout") def post(self): timer = Timer(30, self.timeout_callback) res = processPDF(args) self.write(json.dumps(res))
方案三:参考Tornado请求超时方案
尝试了Tornado请求超时的相关实现方案,但未奏效。
核心疑问
是否有其他方法可以为入站请求设置超时,或使用带超时的线程且不会导致CPU过载?
补充信息
从日志可查看请求到达后的完整耗时,RequestHandler自身会启动计时器:
webservice| 2022-12-02 10:54:34,368 [MainThread] [INFO] Incoming POST request to PdfEx Service: PDF Nr. 123 webservice| 2022-12-02 10:54:36,920 [MainThread] [INFO] Completed POST request to PdfEx Service: PDF Nr. 123 webservice| 2022-12-02 10:54:36,934 [MainThread] [INFO] 200 POST /extract (172.18.0.1) 209651.18ms
内容的提问来源于stack exchange,提问作者LeM4
相关产品推荐
相关产品推荐

