Tornado本身的设计目标是单线程异步非阻塞,要想很好的发挥它的性能最好使用异步IO,并且Tornado本身也提供了异步的AsyncHttpClient的实现,配合gen.coroutine和yield,可以让请求异步执行从而不阻塞当前线程,对于单线程服务器来说,阻塞(blocking)和同步的sleep这种会挂起线程的动作都是服务器的噩梦,因为只有一个线程,所以任何等待都会影响服务器对于其他请求的处理。
异步非阻塞对于第三方IO是http请求的情况还好,毕竟可以使用Tornado提供的异步实现,但是对于有些数据库的IO,则需要异步库的支持,比如针对MongoDB的Motor等。但是第三方异步库的质量也是参差不齐,在实际的工程中,假如没有特别好的异步库的时候,还是只能使用同步的库。
假如只能使用同步阻塞的IO,为了提高性能,可以考虑在Tornado中使用线程池。线程池可以考虑使用concurrent.futures里的ThreadPoolExecutor。
1. 在RequestHandler的http请求处理方法(get/post等)中使用线程池
线程池为RequestHandler持有,请求处理逻辑中的耗时/阻塞任务可以提交给线程池处理,主循环逻辑可以继续处理其他请求,线程池内的任务处理完毕后,会通过回调注册callback到ioloop,ioloop可以通过执行callback恢复挂起的请求处理逻辑。
import tornado.web
import tornado.gen
from tornado.concurrent import run_on_executor
from concurrent.futures import ThreadPo