Tornado 杂项
Tornado系列基本介绍的差不多了,本篇介绍一些零散的东西。有了前面的知识,本篇会讲的比较粗略
set_blocking_signal_threshold
因为Tornado是单线程的,因此当一个任务被阻塞一两秒钟基本就是哪里出问题了,该函数给了我们一个机会察觉这些问题。可以当发生阻塞超过阈值的时候执行相关回调函数
实现原理就是使用信号机制,先使用signal.signal(signal.SIGALRM,callback)
注册信号回调函数。在ioloop主循环中每次事件完成后将实时计时器归零signal.setitimer(signal.ITIMER_REAL, 0, 0)
后再重新开始计时。如果主循环被阻塞没有被执行计时器归零则会被触发
多进程
有一些情况我们会部署多个Tornado实例用来增加系统整体吞吐量,有两种方案,一:将Tornado程序单独执行N份,每一个实例单独监听一个端口,然后使用Nginx实现负载均衡。二:使用Tornado提供的多进程,该模块实现在process.py(最简单的版本为v2.1.0),实现原理为开启一个主进程,开启N个工作进程,主进程主要负责这些工作进程的重启工作(比如某进程挂掉了,那么会重新启动一个,维持总进程数量)。没一个工作进程都有一个主循环,它们均分处理http请求
gen.sleep
等待N秒钟,这个功能直到4.1版本才被加入,还是挺奇怪的。实现原理就是新建一个Future对象,同时添加回调到主循环,设置N秒后将Future对象设置为任意一个值。
gen.run_on_executer
使用单独的线程来完成阻塞的任务。同时能够使用yield异步接收到返回的值。实现原理主要依靠concurrent.future模块,concurrent.future.submit会返回一个Future对象。yield接收到这个对象控制权转移。当线程内容执行完毕后会设置Future的值。yield被恢复
run_sync
经常用于调试。比如写了一个异步函数,要验证一下正确性。那么就不需要使用IOLoop.instance().start()让它无法终止。假设a函数被coroutine装饰,那么a()返回一个Future对象,此时执行IOLoop.instance().start()。整个主循环就会被执行。而run_sync仅仅只是在中间做了一件事情。对于一个Future对象,拥有add_done_callback函数,表示该Future完成后做某事,因此它只是添加了一个回调让主循环停止