关于Python Web框架——Tornado
关于Tornado的入门看这篇文章,写的非常好:
https://zhuanlan.zhihu.com/p/37382503
Tornado 是一个Python web框架和异步网络库,使用非阻塞网络I/O。
Tornado可以被分为4个主要的部分:
- web框架
- HTTP的客户端和服务端实现
- 异步网络库
- 协程库
WSGI是Web Server Gateway Interface的缩写。
实时web功能需要为每个用户提供一个多数时间被闲置的长连接, 在传统的同步web服务器中,这意味着要为每个用户提供一个线程, 当然每个线程的开销都是很昂贵的.
为了尽量减少并发连接造成的开销,Tornado使用了一种单线程事件循环的方式. 这就意味着所有的应用代码都应该是异步非阻塞的, 因为在同一时间只有一个操作是有效的.
知乎和掌阅的后端应该采用了这个框架。
下面提供快速帮助回忆的代码:(阶乘服务和圆周率计算服务)

# pi.py
import json
import math
import redis
import tornado.ioloop
import tornado.web class FactorialService(object): def __init__(self, cache):
self.cache = cache
self.key = "factorials" def calc(self, n):
s = self.cache.hget(self.key, str(n))
if s:
return int(s), True
s = 1
for i in range(1, n):
s *= i
self.cache.hset(self.key, str(n), str(s))
return s, False class PiService(object): def __init__(self, cache):
self.cache = cache
self.key = "pis" def calc(self, n):
s = self.cache.hget(self.key, str(n))
if s:
return float(s), True
s = 0.0
for i in range(n):
s += 1.0/(2*i+1)/(2*i+1)
s = math.sqrt(s*8)
self.cache.hset(self.key, str(n), str(s))
return s, False class FactorialHandler(tornado.web.RequestHandler): def initialize(self, factorial):
self.factorial = factorial def get(self):
n = int(self.get_argument("n") or 1)
fact, cached = self.factorial.calc(n)
result = {
"n": n,
"fact": fact,
"cached": cached
}
self.set_header("Content-Type", "application/json; charset=UTF-8")
self.write(json.dumps(result)) class PiHandler(tornado.web.RequestHandler): def initialize(self, pi):
self.pi = pi def get(self):
n = int(self.get_argument("n") or 1)
pi, cached = self.pi.calc(n)
result = {
"n": n,
"pi": pi,
"cached": cached
}
self.set_header("Content-Type", "application/json; charset=UTF-8")
self.write(json.dumps(result)) def make_app():
cache = redis.StrictRedis("localhost", 6379)
factorial = FactorialService(cache)
pi = PiService(cache)
return tornado.web.Application([
(r"/fact", FactorialHandler, {"factorial": factorial}),
(r"/pi", PiHandler, {"pi": pi}),
]) if __name__ == "__main__":
app = make_app()
app.listen(8888)
tornado.ioloop.IOLoop.current().start()
因为两个Handler都需要用到redis,所以我们将redis单独抽出来,通过参数传递进去。另外Handler可以通过initialize函数传递参数,在注册路由的时候提供一个字典就可以传递任意参数了,字典的key要和参数名称对应。我们运行python pi.py,打开浏览器访问http://localhost:8888/pi?n=200,可以看到浏览器输出{"cached": false, "pi": 3.1412743276, "n": 1000},这个值已经非常接近圆周率了。
下面来自知乎:(写的非常好)
https://zhuanlan.zhihu.com/p/37382503
Tornado:Hello, World
import tornado.ioloop
import tornado.web class MainHandler(tornado.web.RequestHandler):
def get(self):
self.write("Hello, world") def make_app():
return tornado.web.Application([
(r"/", MainHandler),
]) if __name__ == "__main__":
app = make_app()
app.listen(8888)
tornado.ioloop.IOLoop.current().start()
这是官方提供了Hello, World实例,执行python hello.py,打开浏览器访问http://localhost:8888/就可以看到服务器的正常输出Hello, world。
一个普通的tornado web服务器通常由四大组件组成。
- ioloop实例,它是全局的tornado事件循环,是服务器的引擎核心,示例中tornado.ioloop.IOLoop.current()就是默认的tornado ioloop实例。
- app实例,它代表着一个完成的后端app,它会挂接一个服务端套接字端口对外提供服务。一个ioloop实例里面可以有多个app实例,示例中只有1个,实际上可以允许多个,不过一般几乎不会使用多个。
- handler类,它代表着业务逻辑,我们进行服务端开发时就是编写一堆一堆的handler用来服务客户端请求。
- 路由表,它将指定的url规则和handler挂接起来,形成一个路由映射表。当请求到来时,根据请求的访问url查询路由映射表来找到相应的业务handler。
这四大组件的关系是,一个ioloop包含多个app(管理多个服务端口),一个app包含一个路由表,一个路由表包含多个handler。ioloop是服务的引擎核心,它是发动机,负责接收和响应客户端请求,负责驱动业务handler的运行,负责服务器内部定时任务的执行。
当一个请求到来时,ioloop读取这个请求解包成一个http请求对象,找到该套接字上对应app的路由表,通过请求对象的url查询路由表中挂接的handler,然后执行handler。handler方法执行后一般会返回一个对象,ioloop负责将对象包装成http响应对象序列化发送给客户端。

同一个ioloop实例运行在一个单线程环境下。
关于ioloop:
tornado.ioloop — Main event loop
An I/O event loop for non-blocking sockets.(非阻塞套接字接口)
IOLoop is a wrapper around the asyncio event loop. (异步事件循环)
参考:
https://tornado-zh.readthedocs.io/zh/latest/guide/async.html
https://zhuanlan.zhihu.com/p/37382503
https://www.tornadoweb.org/en/stable/ioloop.html
关于Python Web框架——Tornado的更多相关文章
- Python Web框架 tornado 异步原理
		Python Web框架 tornado 异步原理 参考:http://www.jb51.net/article/64747.htm 待整理 
- Python web框架 Tornado异步非阻塞
		Python web框架 Tornado异步非阻塞 异步非阻塞 阻塞式:(适用于所有框架,Django,Flask,Tornado,Bottle) 一个请求到来未处理完成,后续一直等待 解决方案: ... 
- 异步非阻塞IO的Python Web框架--Tornado
		Tornado的全称是Torado Web Server,从名字上就可知它可用作Web服务器,但同时它也是一个Python Web的开发框架.最初是在FriendFeed公司的网站上使用,FaceBo ... 
- Python web框架——Tornado
		Tornado是一个Python Web框架和异步网络库,最初由FriendFeed开发.通过使用非阻塞网络I / O,Tornado可以扩展到数万个开放连接,使其成为需要长时间连接每个用户的长轮询, ... 
- Python Web框架Tornado的异步处理代码演示样例
		1. What is Tornado Tornado是一个轻量级但高性能的Python web框架,与还有一个流行的Python web框架Django相比.tornado不提供操作数据库的ORM接口 ... 
- Python web框架 Tornado(三)自定义session组件
		我们在学习Django框架的过程中,内部封装了session组件,以方便于我们使用进行验证.但是Tornado框架是没有session的,所以如果想使用session的话,就需要我们自己定制相对应的组 ... 
- Python web框架 Tornado(一)基础学习
		概述 Tornado 是 FriendFeed 使用的可扩展的非阻塞式 web 服务器及其相关工具的开源版本.这个 Web 框架看起来有些像web.py 或者 Google 的 webapp,不过为了 ... 
- Python web框架 Tornado(二)异步非阻塞
		异步非阻塞 阻塞式:(适用于所有框架,Django,Flask,Tornado,Bottle) 一个请求到来未处理完成,后续一直等待 解决方案:多线程,多进程 异步非阻塞(存在IO请求): Torna ... 
- Django,Flask,Tornado三大框架对比,Python几种主流框架,13个Python web框架比较,2018年Python web五大主流框架
		Django 与 Tornado 各自的优缺点Django优点: 大和全(重量级框架)自带orm,template,view 需要的功能也可以去找第三方的app注重高效开发全自动化的管理后台(只需要使 ... 
随机推荐
- BZOJ 3052/Luogu P4074 [wc2013]糖果公园 (树上带修莫队)
			题面 中文题面,难得解释了 BZOJ传送门 Luogu传送门 分析 树上带修莫队板子题... 开始没给分块大小赋初值T了好一会... CODE #include <bits/stdc++.h&g ... 
- mysql数据表结构查询
			select * from ( select '表名', '字段名', '字段类型', '默认值', '是否可空', '注释', '主键' UNION ( SELECT a.TABLE_NAME '表 ... 
- springboot2.0入门(九)-- springboot使用mybatis-generator自动代码生成
			一.配置文件引入 插件引入,引入 <plugin> <groupId>org.mybatis.generator</groupId> <artifactId& ... 
- 利用Js的console对象,在控制台打印调式信息测试Js
			一次偶然的机会,打开百度的时候按下了F12,然后就见控制台里面输出了百度的招聘广告,感觉挺帅气的,再然后就有了这篇博文. 既然可以这样在控制台输出信息,那以后再调试Js的时候不就可以省去很多麻烦了嘛! ... 
- 03_mysql-python模块, linux环境下python2,python3的
			---恢复内容开始--- 1.Python2 正常 [root@IP ~]# pip install mysql-python DEPRECATION: Python 2.7 will reach t ... 
- DisplayModeProvider完成移动开发自动视图解析
			MVC中新建视图命名:XXX.cshtml.XXX.mobile.cshtml:用手机访问会自动到xxx.mobile.cshtml 一.原理 MVC中是通过DisplayModeProvider实现 ... 
- Jenkins 自动化构建
			def pipeId = 1130561944231279390 def pipeLogId def isTagOrBranch def tagOrBranch def imageId def add ... 
- win下安装jupyter遇到的问题
			一:安装jupyter 1.首先要用管理员方式打开cmd,没用管理员打开后面安装不上. 2.安装jupyter.我用的是python3,所以用pip3 install jupyter进行安装. 3.安 ... 
- pandas常用操作命令大全
			网上的有个别不对 实际敲了一下 有补充了点常用的环境IDE anaconda python3.7 在这个速查手册中,我们使用如下缩写: df:任意的Pandas DataFrame对象 s:任意的 ... 
- 在树莓派4b上安装 ROS MELODIC 源码安装
			按照以下步骤照做就可以了,很简单的,就是浪费一点点时间罢了.也可以退而求其次,买个树莓派3B+来玩,哈哈. Step 1: Install Dependecies and Download the P ... 
