Python中使用Tornado监听多个HTTPS端口响应慢如何解决
问题原因
你使用的两种多端口监听写法本身不存在性能缺陷,响应速度慢和端口绑定的API调用方式没有直接关系:
- 单端口监听时,入口流量上限低,请求量刚好处于单进程Tornado事件循环可承载的阈值内,阻塞问题没有暴露
- 开启多端口后,请求接入入口变多,总并发量上升,单进程IOLoop串行处理回调的模式下,只要业务代码中存在同步阻塞逻辑(同步数据库查询、本地文件读写、CPU密集计算未做异步隔离),所有端口的请求都会被阻塞排队,直接表现就是整体响应变慢
- 额外注意:你贴的第二种实现代码存在逻辑错误,仅绑定了8082单个端口,并未实现多端口同时监听的效果,测试前需要先修正这部分问题
优化方案
1. 优先清理主事件循环的阻塞逻辑
这是90%以上Tornado性能异常的核心诱因,和监听端口数量无关,只是多端口场景下并发提升把问题放大了:
- 所有不涉及Tornado异步生态的同步IO操作、CPU密集型计算,全部通过
IOLoop.current().run_in_executor扔到独立的线程池/进程池执行,绝对不能直接在请求处理协程里同步运行,避免阻塞整个事件循环 - 不要在请求处理方法里调用任何会阻塞等待的同步方法,所有第三方SDK、数据库驱动优先使用异步实现版本
2. 开启多进程模式承载多端口流量
单进程Tornado只能用到一个CPU核心,多端口接入流量上来之后自然会出现性能瓶颈,使用官方支持的多进程模式即可。注意多进程模式必须先绑定所有端口的套接字再fork进程,不要直接多次调用listen后开多进程,避免套接字继承异常,参考实现代码:
import tornado.httpserver import tornado.ioloop import tornado.netutil if __name__ == "__main__": # 第一步:提前绑定所有需要监听的端口套接字 all_sockets = [] listen_ports = [8080, 8082, 8200] for port in listen_ports: all_sockets.extend(tornado.netutil.bind_sockets(port, address="0.0.0.0")) # 第二步:初始化HTTP服务,注入所有绑定好的套接字 server = tornado.httpserver.HTTPServer(application) server.add_sockets(all_sockets) # 第三步:启动多进程,num_processes=0表示自动匹配CPU核心数启动对应数量的工作进程 # 注意:这行代码执行前不要初始化全局数据库连接、不要启动后台线程,避免fork后出现资源异常 server.start(num_processes=0) # 第四步:启动事件循环 tornado.ioloop.IOLoop.current().start()
3. 补充说明
多次调用同一个HTTPServer实例的listen方法绑定多端口、提前绑定套接字后调用add_sockets注入服务,这两种写法在单进程模式下的性能表现完全一致,不存在性能差异,不需要在这两种写法上反复调试。如果不同端口对应的业务逻辑完全隔离,也可以为每个端口单独初始化HTTPServer实例,统一挂载到同一个IOLoop上运行,这种写法本身也不会带来额外性能损耗。
内容的提问来源于stack exchange,提问作者mohan gowda
相关产品推荐
相关产品推荐

